@@ -47,6 +47,31 @@ using namespace swift;
4747static const Decl *
4848concreteSyntaxDeclForAvailableAttribute (const Decl *AbstractSyntaxDecl);
4949
50+ // / Emit a diagnostic for references to declarations that have been
51+ // / marked as unavailable, either through "unavailable" or "obsoleted:".
52+ static bool diagnoseExplicitUnavailability (
53+ SourceLoc loc, const RootProtocolConformance *rootConf,
54+ const ExtensionDecl *ext, const ExportContext &where,
55+ bool warnIfConformanceUnavailablePreSwift6 = false );
56+
57+ // / Emit a diagnostic for references to declarations that have been
58+ // / marked as unavailable, either through "unavailable" or "obsoleted:".
59+ static bool diagnoseExplicitUnavailability (
60+ const ValueDecl *D, SourceRange R, const ExportContext &Where,
61+ DeclAvailabilityFlags Flags,
62+ llvm::function_ref<void (InFlightDiagnostic &)> attachRenameFixIts);
63+
64+ static bool diagnoseSubstitutionMapAvailability (
65+ SourceLoc loc, SubstitutionMap subs, const ExportContext &where,
66+ Type depTy = Type(), Type replacementTy = Type(),
67+ bool warnIfConformanceUnavailablePreSwift6 = false,
68+ bool suppressParameterizationCheckForOptional = false);
69+
70+ // / Diagnose uses of unavailable declarations in types.
71+ static bool
72+ diagnoseTypeReprAvailability (const TypeRepr *T, const ExportContext &where,
73+ DeclAvailabilityFlags flags = std::nullopt );
74+
5075ExportContext::ExportContext (DeclContext *DC, AvailabilityContext availability,
5176 FragileFunctionKind kind, bool spi, bool exported,
5277 bool implicit)
@@ -2057,7 +2082,7 @@ static void fixAvailability(SourceRange ReferenceRange,
20572082 }
20582083}
20592084
2060- void TypeChecker:: diagnosePotentialUnavailability (
2085+ static void diagnosePotentialUnavailability (
20612086 SourceRange ReferenceRange, Diag<StringRef, llvm::VersionTuple> Diag,
20622087 const DeclContext *ReferenceDC, const AvailabilityRange &Availability) {
20632088 ASTContext &Context = ReferenceDC->getASTContext ();
@@ -2139,10 +2164,14 @@ static Diagnostic getPotentialUnavailabilityDiagnostic(
21392164 Availability.getRawMinimumVersion ());
21402165}
21412166
2142- bool TypeChecker::diagnosePotentialUnavailability (
2143- const ValueDecl *D, SourceRange ReferenceRange,
2144- const DeclContext *ReferenceDC, const AvailabilityRange &Availability,
2145- bool WarnBeforeDeploymentTarget = false ) {
2167+ // Emits a diagnostic for a reference to a declaration that is potentially
2168+ // unavailable at the given source location. Returns true if an error diagnostic
2169+ // was emitted.
2170+ static bool
2171+ diagnosePotentialUnavailability (const ValueDecl *D, SourceRange ReferenceRange,
2172+ const DeclContext *ReferenceDC,
2173+ const AvailabilityRange &Availability,
2174+ bool WarnBeforeDeploymentTarget = false ) {
21462175 ASTContext &Context = ReferenceDC->getASTContext ();
21472176
21482177 bool IsError;
@@ -2162,7 +2191,9 @@ bool TypeChecker::diagnosePotentialUnavailability(
21622191 return IsError;
21632192}
21642193
2165- void TypeChecker::diagnosePotentialAccessorUnavailability (
2194+ // / Emits a diagnostic for a reference to a storage accessor that is
2195+ // / potentially unavailable.
2196+ static void diagnosePotentialAccessorUnavailability (
21662197 const AccessorDecl *Accessor, SourceRange ReferenceRange,
21672198 const DeclContext *ReferenceDC, const AvailabilityRange &Availability,
21682199 bool ForInout) {
@@ -2207,10 +2238,13 @@ behaviorLimitForExplicitUnavailability(
22072238 return DiagnosticBehavior::Unspecified;
22082239}
22092240
2210- void TypeChecker::diagnosePotentialUnavailability (
2211- const RootProtocolConformance *rootConf, const ExtensionDecl *ext,
2212- SourceLoc loc, const DeclContext *dc,
2213- const AvailabilityRange &availability) {
2241+ // / Emits a diagnostic for a protocol conformance that is potentially
2242+ // / unavailable at the given source location.
2243+ static void
2244+ diagnosePotentialUnavailability (const RootProtocolConformance *rootConf,
2245+ const ExtensionDecl *ext, SourceLoc loc,
2246+ const DeclContext *dc,
2247+ const AvailabilityRange &availability) {
22142248 ASTContext &ctx = dc->getASTContext ();
22152249
22162250 {
@@ -2233,7 +2267,9 @@ void TypeChecker::diagnosePotentialUnavailability(
22332267 fixAvailability (loc, dc, availability, ctx);
22342268}
22352269
2236- const AvailableAttr *TypeChecker::getDeprecated (const Decl *D) {
2270+ // / Returns the availability attribute indicating deprecation of the
2271+ // / declaration is deprecated or null otherwise.
2272+ static const AvailableAttr *getDeprecated (const Decl *D) {
22372273 auto &Ctx = D->getASTContext ();
22382274 if (auto *Attr = D->getAttrs ().getDeprecated (Ctx))
22392275 return Attr;
@@ -2661,11 +2697,12 @@ describeRename(ASTContext &ctx, const AvailableAttr *attr, const ValueDecl *D,
26612697 return ReplacementDeclKind::None;
26622698}
26632699
2664- void TypeChecker::diagnoseIfDeprecated (SourceRange ReferenceRange,
2665- const ExportContext &Where,
2666- const ValueDecl *DeprecatedDecl,
2667- const Expr *Call) {
2668- const AvailableAttr *Attr = TypeChecker::getDeprecated (DeprecatedDecl);
2700+ // / Emits a diagnostic for a reference to a declaration that is deprecated.
2701+ static void diagnoseIfDeprecated (SourceRange ReferenceRange,
2702+ const ExportContext &Where,
2703+ const ValueDecl *DeprecatedDecl,
2704+ const Expr *Call) {
2705+ const AvailableAttr *Attr = getDeprecated (DeprecatedDecl);
26692706 if (!Attr)
26702707 return ;
26712708
@@ -2745,11 +2782,12 @@ void TypeChecker::diagnoseIfDeprecated(SourceRange ReferenceRange,
27452782 }
27462783}
27472784
2748- bool TypeChecker::diagnoseIfDeprecated (SourceLoc loc,
2749- const RootProtocolConformance *rootConf,
2750- const ExtensionDecl *ext,
2751- const ExportContext &where) {
2752- const AvailableAttr *attr = TypeChecker::getDeprecated (ext);
2785+ // / Emits a diagnostic for a reference to a conformance that is deprecated.
2786+ static bool diagnoseIfDeprecated (SourceLoc loc,
2787+ const RootProtocolConformance *rootConf,
2788+ const ExtensionDecl *ext,
2789+ const ExportContext &where) {
2790+ const AvailableAttr *attr = getDeprecated (ext);
27532791 if (!attr)
27542792 return false ;
27552793
@@ -2971,7 +3009,7 @@ getExplicitUnavailabilityDiagnosticInfo(const Decl *decl,
29713009 }
29723010}
29733011
2974- bool swift:: diagnoseExplicitUnavailability (
3012+ bool diagnoseExplicitUnavailability (
29753013 SourceLoc loc, const RootProtocolConformance *rootConf,
29763014 const ExtensionDecl *ext, const ExportContext &where,
29773015 bool warnIfConformanceUnavailablePreSwift6) {
@@ -3348,10 +3386,8 @@ static void checkFunctionConversionAvailability(Type srcType, Type destType,
33483386 }
33493387}
33503388
3351- bool swift::diagnoseExplicitUnavailability (
3352- const ValueDecl *D,
3353- SourceRange R,
3354- const ExportContext &Where,
3389+ bool diagnoseExplicitUnavailability (
3390+ const ValueDecl *D, SourceRange R, const ExportContext &Where,
33553391 DeclAvailabilityFlags Flags,
33563392 llvm::function_ref<void (InFlightDiagnostic &)> attachRenameFixIts) {
33573393 auto diagnosticInfo = getExplicitUnavailabilityDiagnosticInfo (D, Where);
@@ -4030,11 +4066,11 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
40304066 // Make sure not to diagnose an accessor's deprecation if we already
40314067 // complained about the property/subscript.
40324068 bool isAccessorWithDeprecatedStorage =
4033- accessor && TypeChecker:: getDeprecated (accessor->getStorage ());
4069+ accessor && getDeprecated (accessor->getStorage ());
40344070
40354071 // Diagnose for deprecation
40364072 if (!isAccessorWithDeprecatedStorage)
4037- TypeChecker:: diagnoseIfDeprecated (R, Where, D, call);
4073+ diagnoseIfDeprecated (R, Where, D, call);
40384074
40394075 if (Flags.contains (DeclAvailabilityFlag::AllowPotentiallyUnavailableProtocol)
40404076 && isa<ProtocolDecl>(D))
@@ -4056,11 +4092,10 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
40564092
40574093 if (accessor) {
40584094 bool forInout = Flags.contains (DeclAvailabilityFlag::ForInout);
4059- TypeChecker:: diagnosePotentialAccessorUnavailability (
4060- accessor, R, DC, requiredAvailability, forInout);
4095+ diagnosePotentialAccessorUnavailability (accessor, R, DC,
4096+ requiredAvailability, forInout);
40614097 } else {
4062- if (!TypeChecker::diagnosePotentialUnavailability (D, R, DC,
4063- requiredAvailability))
4098+ if (!diagnosePotentialUnavailability (D, R, DC, requiredAvailability))
40644099 return false ;
40654100 }
40664101
@@ -4246,7 +4281,8 @@ class StmtAvailabilityWalker : public BaseDiagnosticWalker {
42464281 PreWalkResult<Pattern *> walkToPatternPre (Pattern *P) override {
42474282 if (auto *IP = dyn_cast<IsPattern>(P)) {
42484283 auto where = ExportContext::forFunctionBody (DC, P->getLoc ());
4249- diagnoseTypeAvailability (IP->getCastType (), P->getLoc (), where);
4284+ diagnoseTypeAvailability (IP->getCastTypeRepr (), IP->getCastType (),
4285+ P->getLoc (), where, std::nullopt );
42504286 }
42514287
42524288 return Action::Continue (P);
@@ -4346,9 +4382,9 @@ class TypeReprAvailabilityWalker : public ASTWalker {
43464382
43474383}
43484384
4349- bool swift::diagnoseTypeReprAvailability ( const TypeRepr *T,
4350- const ExportContext &where,
4351- DeclAvailabilityFlags flags) {
4385+ // / Diagnose uses of unavailable declarations in types.
4386+ bool diagnoseTypeReprAvailability ( const TypeRepr *T, const ExportContext &where,
4387+ DeclAvailabilityFlags flags) {
43524388 if (!T)
43534389 return false ;
43544390 TypeReprAvailabilityWalker walker (where, flags);
@@ -4441,20 +4477,15 @@ class ProblematicTypeFinder : public TypeDeclFinder {
44414477
44424478}
44434479
4444- void swift::diagnoseTypeAvailability (Type T, SourceLoc loc,
4445- const ExportContext &where,
4446- DeclAvailabilityFlags flags) {
4447- if (!T)
4448- return ;
4449- T.walk (ProblematicTypeFinder (loc, where, flags));
4450- }
4451-
44524480void swift::diagnoseTypeAvailability (const TypeRepr *TR, Type T, SourceLoc loc,
44534481 const ExportContext &where,
44544482 DeclAvailabilityFlags flags) {
44554483 if (diagnoseTypeReprAvailability (TR, where, flags))
44564484 return ;
4457- diagnoseTypeAvailability (T, loc, where, flags);
4485+
4486+ if (!T)
4487+ return ;
4488+ T.walk (ProblematicTypeFinder (loc, where, flags));
44584489}
44594490
44604491static void diagnoseMissingConformance (
@@ -4534,14 +4565,14 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
45344565 auto maybeUnavail = TypeChecker::checkConformanceAvailability (
45354566 rootConf, ext, where);
45364567 if (maybeUnavail.has_value ()) {
4537- TypeChecker:: diagnosePotentialUnavailability (rootConf, ext, loc, DC,
4538- maybeUnavail.value ());
4568+ diagnosePotentialUnavailability (rootConf, ext, loc, DC,
4569+ maybeUnavail.value ());
45394570 maybeEmitAssociatedTypeNote ();
45404571 return true ;
45414572 }
45424573
45434574 // Diagnose for deprecation
4544- if (TypeChecker:: diagnoseIfDeprecated (loc, rootConf, ext, where)) {
4575+ if (diagnoseIfDeprecated (loc, rootConf, ext, where)) {
45454576 maybeEmitAssociatedTypeNote ();
45464577
45474578 // Deprecation is just a warning, so keep going with checking the
@@ -4559,13 +4590,10 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
45594590 return false ;
45604591}
45614592
4562- bool
4563- swift::diagnoseSubstitutionMapAvailability (SourceLoc loc,
4564- SubstitutionMap subs,
4565- const ExportContext &where,
4566- Type depTy, Type replacementTy,
4567- bool warnIfConformanceUnavailablePreSwift6,
4568- bool suppressParameterizationCheckForOptional) {
4593+ bool diagnoseSubstitutionMapAvailability (
4594+ SourceLoc loc, SubstitutionMap subs, const ExportContext &where, Type depTy,
4595+ Type replacementTy, bool warnIfConformanceUnavailablePreSwift6,
4596+ bool suppressParameterizationCheckForOptional) {
45694597 bool hadAnyIssues = false ;
45704598 for (ProtocolConformanceRef conformance : subs.getConformances ()) {
45714599 if (diagnoseConformanceAvailability (loc, conformance, where,
0 commit comments