Skip to content

Commit 0d8f689

Browse files
authored
Merge pull request swiftlang#34306 from apple/revert-33855-availability-inlinable
Revert "[Sema] Fix availability checking in inlinable code"
2 parents 804459d + e509d68 commit 0d8f689

16 files changed

+97
-350
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,16 +2455,10 @@ NOTE(suggest_removing_override, none,
24552455
ERROR(override_less_available,none,
24562456
"overriding %0 must be as available as declaration it overrides",
24572457
(DeclBaseName))
2458-
WARNING(override_less_available_warn,none,
2459-
"overriding %0 must be as available as declaration it overrides",
2460-
(DeclBaseName))
24612458

24622459
ERROR(override_accessor_less_available,none,
24632460
"overriding %0 for %1 must be as available as declaration it overrides",
24642461
(DescriptiveDeclKind, DeclBaseName))
2465-
WARNING(override_accessor_less_available_warn,none,
2466-
"overriding %0 for %1 must be as available as declaration it overrides",
2467-
(DescriptiveDeclKind, DeclBaseName))
24682462

24692463
ERROR(override_let_property,none,
24702464
"cannot override immutable 'let' property %0 with the getter of a 'var'",

include/swift/AST/TypeRefinementContext.h

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -154,23 +154,16 @@ class TypeRefinementContext {
154154

155155
SourceRange SrcRange;
156156

157-
/// Runtime availability information for the code in this context.
158157
AvailabilityContext AvailabilityInfo;
159158

160-
/// Runtime availability information as explicitly declared by attributes
161-
/// for the inlinable code in this context. Compared to AvailabilityInfo,
162-
/// this is not bounded to the minimum deployment OS version.
163-
AvailabilityContext AvailabilityInfoExplicit;
164-
165159
std::vector<TypeRefinementContext *> Children;
166160

167161
TypeRefinementContext(ASTContext &Ctx, IntroNode Node,
168162
TypeRefinementContext *Parent, SourceRange SrcRange,
169-
const AvailabilityContext &Info,
170-
const AvailabilityContext &InfoExplicit);
163+
const AvailabilityContext &Info);
171164

172165
public:
173-
166+
174167
/// Create the root refinement context for the given SourceFile.
175168
static TypeRefinementContext *createRoot(SourceFile *SF,
176169
const AvailabilityContext &Info);
@@ -179,9 +172,8 @@ class TypeRefinementContext {
179172
static TypeRefinementContext *createForDecl(ASTContext &Ctx, Decl *D,
180173
TypeRefinementContext *Parent,
181174
const AvailabilityContext &Info,
182-
const AvailabilityContext &InfoExplicit,
183175
SourceRange SrcRange);
184-
176+
185177
/// Create a refinement context for the Then branch of the given IfStmt.
186178
static TypeRefinementContext *
187179
createForIfStmtThen(ASTContext &Ctx, IfStmt *S, TypeRefinementContext *Parent,
@@ -248,19 +240,11 @@ class TypeRefinementContext {
248240
SourceRange getSourceRange() const { return SrcRange; }
249241

250242
/// Returns the information on what can be assumed present at run time when
251-
/// running code contained in this context, taking into account the minimum
252-
/// deployment target.
243+
/// running code contained in this context.
253244
const AvailabilityContext &getAvailabilityInfo() const {
254245
return AvailabilityInfo;
255246
}
256247

257-
/// Returns the information on what can be assumed present at run time when
258-
/// running code contained in this context if it were to be inlined,
259-
/// without considering the minimum deployment target.
260-
const AvailabilityContext &getAvailabilityInfoExplicit() const {
261-
return AvailabilityInfoExplicit;
262-
}
263-
264248
/// Adds a child refinement context.
265249
void addChild(TypeRefinementContext *Child) {
266250
assert(Child->getSourceRange().isValid());

lib/AST/Availability.cpp

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,8 @@ static bool isBetterThan(const AvailableAttr *newAttr,
144144
return true;
145145

146146
// If they belong to the same platform, the one that introduces later wins.
147-
if (prevAttr->Platform == newAttr->Platform) {
148-
if (newAttr->isUnconditionallyUnavailable())
149-
return true;
150-
if (prevAttr->isUnconditionallyUnavailable())
151-
return false;
147+
if (prevAttr->Platform == newAttr->Platform)
152148
return prevAttr->Introduced.getValue() < newAttr->Introduced.getValue();
153-
}
154149

155150
// If the new attribute's platform inherits from the old one, it wins.
156151
return inheritsAvailabilityFromPlatform(newAttr->Platform,
@@ -163,12 +158,10 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
163158

164159
for (auto Attr : D->getAttrs()) {
165160
auto *AvailAttr = dyn_cast<AvailableAttr>(Attr);
166-
if (AvailAttr == nullptr ||
161+
if (AvailAttr == nullptr || !AvailAttr->Introduced.hasValue() ||
167162
!AvailAttr->isActivePlatform(Ctx) ||
168163
AvailAttr->isLanguageVersionSpecific() ||
169-
AvailAttr->isPackageDescriptionVersionSpecific() ||
170-
(!AvailAttr->Introduced.hasValue() &&
171-
!AvailAttr->isUnconditionallyUnavailable())) {
164+
AvailAttr->isPackageDescriptionVersionSpecific()) {
172165
continue;
173166
}
174167

@@ -179,9 +172,6 @@ AvailabilityInference::annotatedAvailableRange(const Decl *D, ASTContext &Ctx) {
179172
if (!bestAvailAttr)
180173
return None;
181174

182-
if (bestAvailAttr->isUnconditionallyUnavailable())
183-
return AvailabilityContext(VersionRange::empty());
184-
185175
return AvailabilityContext{
186176
VersionRange::allGTE(bestAvailAttr->Introduced.getValue())};
187177
}

lib/AST/TypeRefinementContext.cpp

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@ using namespace swift;
2828
TypeRefinementContext::TypeRefinementContext(ASTContext &Ctx, IntroNode Node,
2929
TypeRefinementContext *Parent,
3030
SourceRange SrcRange,
31-
const AvailabilityContext &Info,
32-
const AvailabilityContext &InfoExplicit)
33-
: Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info),
34-
AvailabilityInfoExplicit(InfoExplicit) {
31+
const AvailabilityContext &Info)
32+
: Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info) {
3533
if (Parent) {
3634
assert(SrcRange.isValid());
3735
Parent->addChild(this);
38-
assert(InfoExplicit.isContainedIn(Parent->getAvailabilityInfoExplicit()));
36+
assert(Info.isContainedIn(Parent->getAvailabilityInfo()));
3937
}
4038
Ctx.addDestructorCleanup(Children);
4139
}
@@ -48,20 +46,18 @@ TypeRefinementContext::createRoot(SourceFile *SF,
4846
ASTContext &Ctx = SF->getASTContext();
4947
return new (Ctx)
5048
TypeRefinementContext(Ctx, SF,
51-
/*Parent=*/nullptr, SourceRange(), Info,
52-
AvailabilityContext::alwaysAvailable());
49+
/*Parent=*/nullptr, SourceRange(), Info);
5350
}
5451

5552
TypeRefinementContext *
5653
TypeRefinementContext::createForDecl(ASTContext &Ctx, Decl *D,
5754
TypeRefinementContext *Parent,
5855
const AvailabilityContext &Info,
59-
const AvailabilityContext &InfoExplicit,
6056
SourceRange SrcRange) {
6157
assert(D);
6258
assert(Parent);
6359
return new (Ctx)
64-
TypeRefinementContext(Ctx, D, Parent, SrcRange, Info, InfoExplicit);
60+
TypeRefinementContext(Ctx, D, Parent, SrcRange, Info);
6561
}
6662

6763
TypeRefinementContext *
@@ -72,7 +68,7 @@ TypeRefinementContext::createForIfStmtThen(ASTContext &Ctx, IfStmt *S,
7268
assert(Parent);
7369
return new (Ctx)
7470
TypeRefinementContext(Ctx, IntroNode(S, /*IsThen=*/true), Parent,
75-
S->getThenStmt()->getSourceRange(), Info, Info);
71+
S->getThenStmt()->getSourceRange(), Info);
7672
}
7773

7874
TypeRefinementContext *
@@ -83,7 +79,7 @@ TypeRefinementContext::createForIfStmtElse(ASTContext &Ctx, IfStmt *S,
8379
assert(Parent);
8480
return new (Ctx)
8581
TypeRefinementContext(Ctx, IntroNode(S, /*IsThen=*/false), Parent,
86-
S->getElseStmt()->getSourceRange(), Info, Info);
82+
S->getElseStmt()->getSourceRange(), Info);
8783
}
8884

8985
TypeRefinementContext *
@@ -96,7 +92,7 @@ TypeRefinementContext::createForConditionFollowingQuery(ASTContext &Ctx,
9692
assert(Parent);
9793
SourceRange Range(PAI->getEndLoc(), LastElement.getEndLoc());
9894
return new (Ctx) TypeRefinementContext(Ctx, PAI, Parent, Range,
99-
Info, Info);
95+
Info);
10096
}
10197

10298
TypeRefinementContext *
@@ -111,7 +107,7 @@ TypeRefinementContext::createForGuardStmtFallthrough(ASTContext &Ctx,
111107
SourceRange Range(RS->getEndLoc(), ContainingBraceStmt->getEndLoc());
112108
return new (Ctx) TypeRefinementContext(Ctx,
113109
IntroNode(RS, /*IsFallthrough=*/true),
114-
Parent, Range, Info, Info);
110+
Parent, Range, Info);
115111
}
116112

117113
TypeRefinementContext *
@@ -122,7 +118,7 @@ TypeRefinementContext::createForGuardStmtElse(ASTContext &Ctx, GuardStmt *RS,
122118
assert(Parent);
123119
return new (Ctx)
124120
TypeRefinementContext(Ctx, IntroNode(RS, /*IsFallthrough=*/false), Parent,
125-
RS->getBody()->getSourceRange(), Info, Info);
121+
RS->getBody()->getSourceRange(), Info);
126122
}
127123

128124
TypeRefinementContext *
@@ -132,7 +128,7 @@ TypeRefinementContext::createForWhileStmtBody(ASTContext &Ctx, WhileStmt *S,
132128
assert(S);
133129
assert(Parent);
134130
return new (Ctx) TypeRefinementContext(
135-
Ctx, S, Parent, S->getBody()->getSourceRange(), Info, Info);
131+
Ctx, S, Parent, S->getBody()->getSourceRange(), Info);
136132
}
137133

138134
// Only allow allocation of TypeRefinementContext using the allocator in
@@ -300,7 +296,6 @@ void TypeRefinementContext::print(raw_ostream &OS, SourceManager &SrcMgr,
300296
OS << "(" << getReasonName(getReason());
301297

302298
OS << " versions=" << AvailabilityInfo.getOSVersion().getAsString();
303-
OS << " explicit=" << AvailabilityInfoExplicit.getOSVersion().getAsString();
304299

305300
if (getReason() == Reason::Decl) {
306301
Decl *D = Node.getAsDecl();

lib/ClangImporter/ImportDecl.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,27 +1817,18 @@ static void applyAvailableAttribute(Decl *decl, AvailabilityContext &info,
18171817
if (info.isAlwaysAvailable())
18181818
return;
18191819

1820-
PlatformAgnosticAvailabilityKind platformAgnosticAvailability;
1821-
llvm::VersionTuple introducedVersion;
1822-
if (info.isKnownUnreachable()) {
1823-
platformAgnosticAvailability = PlatformAgnosticAvailabilityKind::Unavailable;
1824-
} else {
1825-
platformAgnosticAvailability = PlatformAgnosticAvailabilityKind::None;
1826-
introducedVersion = info.getOSVersion().getLowerEndpoint();
1827-
}
1828-
18291820
llvm::VersionTuple noVersion;
18301821
auto AvAttr = new (C) AvailableAttr(SourceLoc(), SourceRange(),
18311822
targetPlatform(C.LangOpts),
18321823
/*Message=*/StringRef(),
18331824
/*Rename=*/StringRef(),
1834-
introducedVersion,
1825+
info.getOSVersion().getLowerEndpoint(),
18351826
/*IntroducedRange*/SourceRange(),
18361827
/*Deprecated=*/noVersion,
18371828
/*DeprecatedRange*/SourceRange(),
18381829
/*Obsoleted=*/noVersion,
18391830
/*ObsoletedRange*/SourceRange(),
1840-
platformAgnosticAvailability,
1831+
PlatformAgnosticAvailabilityKind::None,
18411832
/*Implicit=*/false);
18421833

18431834
decl->getAttrs().add(AvAttr);

lib/SIL/IR/SILPrinter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,8 +2638,7 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
26382638
if (isAlwaysWeakImported())
26392639
OS << "[weak_imported] ";
26402640
auto availability = getAvailabilityForLinkage();
2641-
if (!availability.isAlwaysAvailable() &&
2642-
!availability.isKnownUnreachable()) {
2641+
if (!availability.isAlwaysAvailable()) {
26432642
auto version = availability.getOSVersion().getLowerEndpoint();
26442643
OS << "[available " << version.getAsString() << "] ";
26452644
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,16 +1543,9 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
15431543
VersionRange::allGTE(attr->Introduced.getValue())};
15441544

15451545
if (!AttrRange.isContainedIn(EnclosingAnnotatedRange.getValue())) {
1546-
// Don't show this error in swiftinterfaces if it is about a context that
1547-
// is unavailable, this was in the stdlib at Swift 5.3.
1548-
SourceFile *Parent = D->getDeclContext()->getParentSourceFile();
1549-
if (!Parent || Parent->Kind != SourceFileKind::Interface ||
1550-
!EnclosingAnnotatedRange.getValue().isKnownUnreachable()) {
1551-
diagnose(attr->getLocation(),
1552-
diag::availability_decl_more_than_enclosing);
1553-
diagnose(EnclosingDecl->getLoc(),
1554-
diag::availability_decl_more_than_enclosing_enclosing_here);
1555-
}
1546+
diagnose(attr->getLocation(), diag::availability_decl_more_than_enclosing);
1547+
diagnose(EnclosingDecl->getLoc(),
1548+
diag::availability_decl_more_than_enclosing_enclosing_here);
15561549
}
15571550
}
15581551

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -170,30 +170,13 @@ class TypeRefinementContextBuilder : private ASTWalker {
170170
// The potential versions in the declaration are constrained by both
171171
// the declared availability of the declaration and the potential versions
172172
// of its lexical context.
173-
AvailabilityContext ExplicitDeclInfo =
173+
AvailabilityContext DeclInfo =
174174
swift::AvailabilityInference::availableRange(D, Context);
175-
ExplicitDeclInfo.intersectWith(
176-
getCurrentTRC()->getAvailabilityInfoExplicit());
177-
AvailabilityContext DeclInfo = ExplicitDeclInfo;
178-
179-
// When the body is inlinable consider only the explicitly declared range
180-
// for checking availability. Otherwise, use the parent range which may
181-
// begin at the minimum deployment target.
182-
//
183-
// Also use the parent range when reading swiftinterfaces for
184-
// retrocompatibility.
185-
bool isInlinable = D->getAttrs().hasAttribute<InlinableAttr>() ||
186-
D->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>();
187-
SourceFile *SF = D->getDeclContext()->getParentSourceFile();
188-
if (!isInlinable || (SF && SF->Kind == SourceFileKind::Interface)) {
189-
DeclInfo.intersectWith(
190-
getCurrentTRC()->getAvailabilityInfo());
191-
}
175+
DeclInfo.intersectWith(getCurrentTRC()->getAvailabilityInfo());
192176

193177
TypeRefinementContext *NewTRC =
194178
TypeRefinementContext::createForDecl(Context, D, getCurrentTRC(),
195179
DeclInfo,
196-
ExplicitDeclInfo,
197180
refinementSourceRangeForDecl(D));
198181

199182
// Record the TRC for this storage declaration so that
@@ -207,27 +190,19 @@ class TypeRefinementContextBuilder : private ASTWalker {
207190

208191
return NewTRC;
209192
}
210-
193+
211194
/// Returns true if the declaration should introduce a new refinement context.
212195
bool declarationIntroducesNewContext(Decl *D) {
213196
if (!isa<ValueDecl>(D) && !isa<ExtensionDecl>(D)) {
214197
return false;
215198
}
216-
217-
// Explicit inlinability may to the decl being used on an earlier OS
218-
// version when inlined on the client side. This check assumes that
219-
// implicit decls are handled elsewhere.
220-
bool isExplicitlyInlinable = !D->isImplicit() &&
221-
(D->getAttrs().hasAttribute<InlinableAttr>() ||
222-
D->getAttrs().hasAttribute<AlwaysEmitIntoClientAttr>());
223-
199+
224200
// No need to introduce a context if the declaration does not have an
225-
// availability or non-implicit inlinable attribute.
226-
if (!hasActiveAvailableAttribute(D, Context) &&
227-
!isExplicitlyInlinable) {
201+
// availability attribute.
202+
if (!hasActiveAvailableAttribute(D, Context)) {
228203
return false;
229204
}
230-
205+
231206
// Only introduce for an AbstractStorageDecl if it is not local.
232207
// We introduce for the non-local case because these may
233208
// have getters and setters (and these may be synthesized, so they might
@@ -238,7 +213,7 @@ class TypeRefinementContextBuilder : private ASTWalker {
238213
return false;
239214
}
240215
}
241-
216+
242217
return true;
243218
}
244219

@@ -699,7 +674,9 @@ TypeChecker::overApproximateAvailabilityAtLocation(SourceLoc loc,
699674
// refined. For now, this is fine -- but if we ever synthesize #available(),
700675
// this will be a real problem.
701676

702-
auto OverApproximateContext = AvailabilityContext::alwaysAvailable();
677+
// We can assume we are running on at least the minimum deployment target.
678+
auto OverApproximateContext =
679+
AvailabilityContext::forDeploymentTarget(Context);
703680
auto isInvalidLoc = [SF](SourceLoc loc) {
704681
return SF ? loc.isInvalid() : true;
705682
};
@@ -730,14 +707,6 @@ TypeChecker::overApproximateAvailabilityAtLocation(SourceLoc loc,
730707
}
731708
}
732709

733-
// If we still don't have an introduction version, use the current deployment
734-
// target. This covers cases where an inlinable function and its parent
735-
// contexts don't have explicit availability attributes.
736-
if (!OverApproximateContext.getOSVersion().hasLowerEndpoint()) {
737-
auto currentOS = AvailabilityContext::forDeploymentTarget(Context);
738-
OverApproximateContext.constrainWith(currentOS);
739-
}
740-
741710
return OverApproximateContext;
742711
}
743712

0 commit comments

Comments
 (0)