Skip to content

Commit 3934f78

Browse files
authored
Merge pull request #77180 from tshortli/consolidate-availability-typechecking
2 parents 8242110 + 05b95b8 commit 3934f78

File tree

3 files changed

+92
-144
lines changed

3 files changed

+92
-144
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 83 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,31 @@ using namespace swift;
4747
static const Decl *
4848
concreteSyntaxDeclForAvailableAttribute(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+
5075
ExportContext::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-
44524480
void 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

44604491
static 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,

lib/Sema/TypeCheckAvailability.h

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -215,16 +215,6 @@ void diagnoseExprAvailability(const Expr *E, DeclContext *DC);
215215
void diagnoseStmtAvailability(const Stmt *S, DeclContext *DC,
216216
bool walkRecursively=false);
217217

218-
/// Diagnose uses of unavailable declarations in types.
219-
bool diagnoseTypeReprAvailability(const TypeRepr *T,
220-
const ExportContext &context,
221-
DeclAvailabilityFlags flags = std::nullopt);
222-
223-
/// Diagnose uses of unavailable conformances in types.
224-
void diagnoseTypeAvailability(Type T, SourceLoc loc,
225-
const ExportContext &context,
226-
DeclAvailabilityFlags flags = std::nullopt);
227-
228218
/// Checks both a TypeRepr and a Type, but avoids emitting duplicate
229219
/// diagnostics by only checking the Type if the TypeRepr succeeded.
230220
void diagnoseTypeAvailability(const TypeRepr *TR, Type T, SourceLoc loc,
@@ -239,15 +229,6 @@ diagnoseConformanceAvailability(SourceLoc loc,
239229
Type replacementTy=Type(),
240230
bool warnIfConformanceUnavailablePreSwift6 = false);
241231

242-
bool diagnoseSubstitutionMapAvailability(
243-
SourceLoc loc,
244-
SubstitutionMap subs,
245-
const ExportContext &context,
246-
Type depTy = Type(),
247-
Type replacementTy = Type(),
248-
bool warnIfConformanceUnavailablePreSwift6 = false,
249-
bool suppressParameterizationCheckForOptional = false);
250-
251232
/// Diagnose uses of unavailable declarations. Returns true if a diagnostic
252233
/// was emitted.
253234
bool diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
@@ -267,24 +248,6 @@ bool diagnoseExplicitUnavailability(const ValueDecl *D, SourceRange R,
267248
const Expr *call,
268249
DeclAvailabilityFlags Flags = std::nullopt);
269250

270-
/// Emit a diagnostic for references to declarations that have been
271-
/// marked as unavailable, either through "unavailable" or "obsoleted:".
272-
bool diagnoseExplicitUnavailability(
273-
const ValueDecl *D,
274-
SourceRange R,
275-
const ExportContext &Where,
276-
DeclAvailabilityFlags Flags,
277-
llvm::function_ref<void(InFlightDiagnostic &)> attachRenameFixIts);
278-
279-
/// Emit a diagnostic for references to declarations that have been
280-
/// marked as unavailable, either through "unavailable" or "obsoleted:".
281-
bool diagnoseExplicitUnavailability(
282-
SourceLoc loc,
283-
const RootProtocolConformance *rootConf,
284-
const ExtensionDecl *ext,
285-
const ExportContext &where,
286-
bool warnIfConformanceUnavailablePreSwift6 = false);
287-
288251
/// Diagnose uses of the runtime support of the given type, such as
289252
/// type metadata and dynamic casting.
290253
///

0 commit comments

Comments
 (0)