Skip to content

Commit ac98262

Browse files
committed
Sema: Adopt AvailabilityContext in ExportContext.
Query for an AvailabilityContext instead of computing availability with a DeclContext traversal when forming an ExportContext.
1 parent 536e666 commit ac98262

File tree

4 files changed

+36
-82
lines changed

4 files changed

+36
-82
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 25 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,13 @@ using namespace swift;
4747
static const Decl *
4848
concreteSyntaxDeclForAvailableAttribute(const Decl *AbstractSyntaxDecl);
4949

50-
ExportContext::ExportContext(
51-
DeclContext *DC, AvailabilityRange runningOSVersion,
52-
FragileFunctionKind kind, bool spi, bool exported, bool implicit,
53-
bool deprecated, std::optional<PlatformKind> unavailablePlatformKind)
54-
: DC(DC), RunningOSVersion(runningOSVersion), FragileKind(kind) {
50+
ExportContext::ExportContext(DeclContext *DC, AvailabilityContext availability,
51+
FragileFunctionKind kind, bool spi, bool exported,
52+
bool implicit)
53+
: DC(DC), Availability(availability), FragileKind(kind) {
5554
SPI = spi;
5655
Exported = exported;
5756
Implicit = implicit;
58-
Deprecated = deprecated;
59-
if (unavailablePlatformKind) {
60-
Unavailable = 1;
61-
Platform = unsigned(*unavailablePlatformKind);
62-
} else {
63-
Unavailable = 0;
64-
Platform = 0;
65-
}
66-
6757
Reason = unsigned(ExportabilityReason::General);
6858
}
6959

@@ -196,10 +186,8 @@ static void forEachOuterDecl(DeclContext *DC, Fn fn) {
196186
}
197187
}
198188

199-
static void
200-
computeExportContextBits(ASTContext &Ctx, Decl *D, bool *spi, bool *implicit,
201-
bool *deprecated,
202-
std::optional<PlatformKind> *unavailablePlatformKind) {
189+
static void computeExportContextBits(ASTContext &Ctx, Decl *D, bool *spi,
190+
bool *implicit) {
203191
if (D->isSPI() ||
204192
D->isAvailableAsSPI())
205193
*spi = true;
@@ -211,18 +199,10 @@ computeExportContextBits(ASTContext &Ctx, Decl *D, bool *spi, bool *implicit,
211199
if (D->isImplicit() && !isDeferBody)
212200
*implicit = true;
213201

214-
if (D->getAttrs().isDeprecated(Ctx))
215-
*deprecated = true;
216-
217-
if (auto *A = D->getAttrs().getUnavailable(Ctx)) {
218-
*unavailablePlatformKind = A->Platform;
219-
}
220-
221202
if (auto *PBD = dyn_cast<PatternBindingDecl>(D)) {
222203
for (unsigned i = 0, e = PBD->getNumPatternEntries(); i < e; ++i) {
223204
if (auto *VD = PBD->getAnchoringVarDecl(i))
224-
computeExportContextBits(Ctx, VD, spi, implicit, deprecated,
225-
unavailablePlatformKind);
205+
computeExportContextBits(Ctx, VD, spi, implicit);
226206
}
227207
}
228208
}
@@ -232,56 +212,40 @@ ExportContext ExportContext::forDeclSignature(Decl *D) {
232212

233213
auto *DC = D->getInnermostDeclContext();
234214
auto fragileKind = DC->getFragileFunctionKind();
235-
auto runningOSVersion =
215+
auto availabilityContext =
236216
(Ctx.LangOpts.DisableAvailabilityChecking
237-
? AvailabilityRange::alwaysAvailable()
238-
: TypeChecker::overApproximateAvailabilityAtLocation(D->getLoc(),
239-
DC));
217+
? AvailabilityContext::getDefault(Ctx)
218+
: TypeChecker::availabilityAtLocation(D->getLoc(), DC));
240219
bool spi = Ctx.LangOpts.LibraryLevel == LibraryLevel::SPI;
241220
bool implicit = false;
242-
bool deprecated = false;
243-
std::optional<PlatformKind> unavailablePlatformKind;
244-
computeExportContextBits(Ctx, D, &spi, &implicit, &deprecated,
245-
&unavailablePlatformKind);
246-
forEachOuterDecl(D->getDeclContext(),
247-
[&](Decl *D) {
248-
computeExportContextBits(Ctx, D,
249-
&spi, &implicit, &deprecated,
250-
&unavailablePlatformKind);
251-
});
221+
computeExportContextBits(Ctx, D, &spi, &implicit);
222+
forEachOuterDecl(D->getDeclContext(), [&](Decl *D) {
223+
computeExportContextBits(Ctx, D, &spi, &implicit);
224+
});
252225

253226
bool exported = ::isExported(D);
254227

255-
return ExportContext(DC, runningOSVersion, fragileKind,
256-
spi, exported, implicit, deprecated,
257-
unavailablePlatformKind);
228+
return ExportContext(DC, availabilityContext, fragileKind, spi, exported,
229+
implicit);
258230
}
259231

260232
ExportContext ExportContext::forFunctionBody(DeclContext *DC, SourceLoc loc) {
261233
auto &Ctx = DC->getASTContext();
262234

263235
auto fragileKind = DC->getFragileFunctionKind();
264-
auto runningOSVersion =
236+
auto availabilityContext =
265237
(Ctx.LangOpts.DisableAvailabilityChecking
266-
? AvailabilityRange::alwaysAvailable()
267-
: TypeChecker::overApproximateAvailabilityAtLocation(loc, DC));
268-
238+
? AvailabilityContext::getDefault(Ctx)
239+
: TypeChecker::availabilityAtLocation(loc, DC));
269240
bool spi = Ctx.LangOpts.LibraryLevel == LibraryLevel::SPI;
270241
bool implicit = false;
271-
bool deprecated = false;
272-
std::optional<PlatformKind> unavailablePlatformKind;
273-
forEachOuterDecl(DC,
274-
[&](Decl *D) {
275-
computeExportContextBits(Ctx, D,
276-
&spi, &implicit, &deprecated,
277-
&unavailablePlatformKind);
278-
});
242+
forEachOuterDecl(
243+
DC, [&](Decl *D) { computeExportContextBits(Ctx, D, &spi, &implicit); });
279244

280245
bool exported = false;
281246

282-
return ExportContext(DC, runningOSVersion, fragileKind,
283-
spi, exported, implicit, deprecated,
284-
unavailablePlatformKind);
247+
return ExportContext(DC, availabilityContext, fragileKind, spi, exported,
248+
implicit);
285249
}
286250

287251
ExportContext ExportContext::forConformance(DeclContext *DC,
@@ -310,16 +274,11 @@ ExportContext ExportContext::withExported(bool exported) const {
310274
ExportContext ExportContext::withRefinedAvailability(
311275
const AvailabilityRange &availability) const {
312276
auto copy = *this;
313-
copy.RunningOSVersion.intersectWith(availability);
277+
copy.Availability.constrainWithPlatformRange(availability,
278+
DC->getASTContext());
314279
return copy;
315280
}
316281

317-
std::optional<PlatformKind> ExportContext::getUnavailablePlatformKind() const {
318-
if (Unavailable)
319-
return PlatformKind(Platform);
320-
return std::nullopt;
321-
}
322-
323282
bool ExportContext::mustOnlyReferenceExportedDecls() const {
324283
return Exported || FragileKind.kind != FragileFunctionKind::None;
325284
}

lib/Sema/TypeCheckAvailability.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define SWIFT_SEMA_TYPE_CHECK_AVAILABILITY_H
1515

1616
#include "swift/AST/AttrKind.h"
17-
#include "swift/AST/Availability.h"
17+
#include "swift/AST/AvailabilityContext.h"
1818
#include "swift/AST/DeclContext.h"
1919
#include "swift/AST/Identifier.h"
2020
#include "swift/Basic/LLVM.h"
@@ -103,20 +103,16 @@ enum class ExportabilityReason : unsigned {
103103
/// without producing a warning or error, respectively.
104104
class ExportContext {
105105
DeclContext *DC;
106-
AvailabilityRange RunningOSVersion;
106+
AvailabilityContext Availability;
107107
FragileFunctionKind FragileKind;
108108
unsigned SPI : 1;
109109
unsigned Exported : 1;
110-
unsigned Deprecated : 1;
111110
unsigned Implicit : 1;
112-
unsigned Unavailable : 1;
113-
unsigned Platform : 8;
114111
unsigned Reason : 3;
115112

116-
ExportContext(DeclContext *DC, AvailabilityRange runningOSVersion,
113+
ExportContext(DeclContext *DC, AvailabilityContext availability,
117114
FragileFunctionKind kind, bool spi, bool exported,
118-
bool implicit, bool deprecated,
119-
std::optional<PlatformKind> unavailablePlatformKind);
115+
bool implicit);
120116

121117
public:
122118

@@ -161,7 +157,7 @@ class ExportContext {
161157
DeclContext *getDeclContext() const { return DC; }
162158

163159
AvailabilityRange getAvailabilityRange() const {
164-
return RunningOSVersion;
160+
return Availability.getPlatformRange();
165161
}
166162

167163
/// If not 'None', the context has the inlinable function body restriction.
@@ -180,9 +176,11 @@ class ExportContext {
180176

181177
/// If true, the context is part of a deprecated declaration and can
182178
/// reference other deprecated declarations without warning.
183-
bool isDeprecated() const { return Deprecated; }
179+
bool isDeprecated() const { return Availability.isDeprecated(); }
184180

185-
std::optional<PlatformKind> getUnavailablePlatformKind() const;
181+
std::optional<PlatformKind> getUnavailablePlatformKind() const {
182+
return Availability.getUnavailablePlatformKind();
183+
}
186184

187185
/// If true, the context can only reference exported declarations, either
188186
/// because it is the signature context of an exported declaration, or

test/Sema/availability_deprecated_script_mode.swift

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@ var testDeprecatedReferencingDeprecated2: () {
2020
x - y // no-warning
2121
}
2222

23-
// FIXME: This doesn't work because the file is parsed in script mode.
2423
@available(*, deprecated)
2524
var testDeprecatedReferencingDeprecated3: () = DummyType() - DummyType()
26-
// expected-warning@-1 {{'-' is deprecated}}
27-
// expected-note@-2 {{use '&-' instead}}
2825

2926
struct HasDeprecatedMembers {
3027
@available(*, deprecated)
@@ -41,4 +38,4 @@ struct HasDeprecatedMembers {
4138

4239
@available(*, deprecated)
4340
var testDeprecatedReferencingDeprecated3: () = DummyType() - DummyType() // no-warning
44-
}
41+
}

test/attr/attr_availability_transitive_osx.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ extension Outer {
133133

134134
@available(*, unavailable)
135135
func osx_universally_unavailable_call_osx() {
136-
osx() // OK
136+
osx() // expected-error {{'osx()' is unavailable in macOS}}
137137
}
138138

139139
// rdar://92551870

0 commit comments

Comments
 (0)