Skip to content

Commit a35dc48

Browse files
committed
AST: Allow CaptureListExpr to hold any AbstractClosureExpr.
Semantically, the capture list binding behavior doesn't require the scope to be an explicit closure, and forming new ClosureExprs during type-checking is difficult because they have to have preassigned discriminators, unlike AutoClosureExprs which get discriminators introduced by Sema itself. Allowing CaptureListExpr to hold an AutoClosureExpr makes it easier to synthesize CaptureListExprs during type checking, to represent expressions with closure semantics that evaluate some parts of the expression eagerly in the surrounding context.
1 parent f36668e commit a35dc48

File tree

8 files changed

+45
-27
lines changed

8 files changed

+45
-27
lines changed

include/swift/AST/ASTScope.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class ASTScopeImpl : public ASTAllocated<ASTScopeImpl> {
203203

204204
#pragma mark common queries
205205
public:
206-
virtual NullablePtr<ClosureExpr> getClosureIfClosureScope() const;
206+
virtual NullablePtr<AbstractClosureExpr> getClosureIfClosureScope() const;
207207
virtual ASTContext &getASTContext() const;
208208
virtual NullablePtr<Decl> getDeclIfAny() const { return nullptr; };
209209
virtual NullablePtr<Stmt> getStmtIfAny() const { return nullptr; };
@@ -1032,17 +1032,17 @@ class CaptureListScope final : public ASTScopeImpl {
10321032
/// For a closure with named parameters, this scope does the local bindings.
10331033
class ClosureParametersScope final : public ASTScopeImpl {
10341034
public:
1035-
ClosureExpr *const closureExpr;
1035+
AbstractClosureExpr *const closureExpr;
10361036

1037-
ClosureParametersScope(ClosureExpr *closureExpr)
1037+
ClosureParametersScope(AbstractClosureExpr *closureExpr)
10381038
: closureExpr(closureExpr) {}
10391039
virtual ~ClosureParametersScope() {}
10401040

10411041
std::string getClassName() const override;
10421042
SourceRange
10431043
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
10441044

1045-
NullablePtr<ClosureExpr> getClosureIfClosureScope() const override {
1045+
NullablePtr<AbstractClosureExpr> getClosureIfClosureScope() const override {
10461046
return closureExpr;
10471047
}
10481048
NullablePtr<Expr> getExprIfAny() const override { return closureExpr; }
@@ -1541,7 +1541,7 @@ class BraceStmtScope final : public AbstractStmtScope {
15411541
SourceRange
15421542
getSourceRangeOfThisASTNode(bool omitAssertions = false) const override;
15431543

1544-
NullablePtr<ClosureExpr> parentClosureIfAny() const; // public??
1544+
NullablePtr<AbstractClosureExpr> parentClosureIfAny() const; // public??
15451545
Stmt *getStmt() const override { return stmt; }
15461546

15471547
protected:

include/swift/AST/Expr.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4144,10 +4144,10 @@ class CaptureListExpr final : public Expr,
41444144
private llvm::TrailingObjects<CaptureListExpr, CaptureListEntry> {
41454145
friend TrailingObjects;
41464146

4147-
ClosureExpr *closureBody;
4147+
AbstractClosureExpr *closureBody;
41484148

41494149
CaptureListExpr(ArrayRef<CaptureListEntry> captureList,
4150-
ClosureExpr *closureBody)
4150+
AbstractClosureExpr *closureBody)
41514151
: Expr(ExprKind::CaptureList, /*Implicit=*/false, Type()),
41524152
closureBody(closureBody) {
41534153
Bits.CaptureListExpr.NumCaptures = captureList.size();
@@ -4158,16 +4158,16 @@ class CaptureListExpr final : public Expr,
41584158
public:
41594159
static CaptureListExpr *create(ASTContext &ctx,
41604160
ArrayRef<CaptureListEntry> captureList,
4161-
ClosureExpr *closureBody);
4161+
AbstractClosureExpr *closureBody);
41624162

41634163
ArrayRef<CaptureListEntry> getCaptureList() {
41644164
return {getTrailingObjects<CaptureListEntry>(),
41654165
Bits.CaptureListExpr.NumCaptures};
41664166
}
4167-
ClosureExpr *getClosureBody() { return closureBody; }
4168-
const ClosureExpr *getClosureBody() const { return closureBody; }
4167+
AbstractClosureExpr *getClosureBody() { return closureBody; }
4168+
const AbstractClosureExpr *getClosureBody() const { return closureBody; }
41694169

4170-
void setClosureBody(ClosureExpr *body) { closureBody = body; }
4170+
void setClosureBody(AbstractClosureExpr *body) { closureBody = body; }
41714171

41724172
/// This is a bit weird, but the capture list is lexically contained within
41734173
/// the closure, so the ClosureExpr has the full source range.

lib/AST/ASTScope.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ Pattern *AbstractPatternEntryScope::getPattern() const {
8383
return getPatternEntry().getPattern();
8484
}
8585

86-
NullablePtr<ClosureExpr> BraceStmtScope::parentClosureIfAny() const {
86+
NullablePtr<AbstractClosureExpr> BraceStmtScope::parentClosureIfAny() const {
8787
return !getParent() ? nullptr : getParent().get()->getClosureIfClosureScope();
8888
}
8989

90-
NullablePtr<ClosureExpr> ASTScopeImpl::getClosureIfClosureScope() const {
90+
NullablePtr<AbstractClosureExpr> ASTScopeImpl::getClosureIfClosureScope() const {
9191
return nullptr;
9292
}
9393

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,9 +283,12 @@ SourceRange
283283
BraceStmtScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
284284
// The brace statements that represent closures start their scope at the
285285
// 'in' keyword, when present.
286-
if (auto closure = parentClosureIfAny()) {
287-
if (closure.get()->getInLoc().isValid())
288-
return SourceRange(closure.get()->getInLoc(), endLoc);
286+
if (auto anyClosure = parentClosureIfAny()) {
287+
if (auto closure = dyn_cast<ClosureExpr>(parentClosureIfAny().get())) {
288+
if (closure->getInLoc().isValid()) {
289+
return SourceRange(closure->getInLoc(), endLoc);
290+
}
291+
}
289292
}
290293
return SourceRange(stmt->getStartLoc(), endLoc);
291294
}
@@ -302,7 +305,10 @@ SourceRange ConditionalClausePatternUseScope::getSourceRangeOfThisASTNode(
302305

303306
SourceRange
304307
CaptureListScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
305-
auto *closureExpr = expr->getClosureBody();
308+
if (auto autoClosure = dyn_cast<AutoClosureExpr>(expr->getClosureBody())) {
309+
return autoClosure->getSourceRange();
310+
}
311+
auto closureExpr = cast<ClosureExpr>(expr->getClosureBody());
306312
if (!omitAssertions)
307313
ASTScopeAssert(closureExpr->getInLoc().isValid(),
308314
"We don't create these if no in loc");
@@ -311,10 +317,16 @@ CaptureListScope::getSourceRangeOfThisASTNode(const bool omitAssertions) const {
311317

312318
SourceRange ClosureParametersScope::getSourceRangeOfThisASTNode(
313319
const bool omitAssertions) const {
314-
if (closureExpr->getInLoc().isValid())
315-
return SourceRange(closureExpr->getInLoc(), closureExpr->getEndLoc());
320+
if (auto autoClosure = dyn_cast<AutoClosureExpr>(closureExpr)) {
321+
return autoClosure->getSourceRange();
322+
}
323+
auto explicitClosureExpr = cast<ClosureExpr>(closureExpr);
324+
if (explicitClosureExpr->getInLoc().isValid()) {
325+
return SourceRange(explicitClosureExpr->getInLoc(),
326+
explicitClosureExpr->getEndLoc());
327+
}
316328

317-
return closureExpr->getSourceRange();
329+
return explicitClosureExpr->getSourceRange();
318330
}
319331

320332
SourceRange AttachedPropertyWrapperScope::getSourceRangeOfThisASTNode(

lib/AST/ASTWalker.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,8 +848,8 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
848848
}
849849
}
850850

851-
ClosureExpr *body = expr->getClosureBody();
852-
if ((body = cast_or_null<ClosureExpr>(doIt(body))))
851+
AbstractClosureExpr *body = expr->getClosureBody();
852+
if ((body = cast_or_null<AbstractClosureExpr>(doIt(body))))
853853
expr->setClosureBody(body);
854854
else
855855
return nullptr;

lib/AST/Expr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1302,7 +1302,7 @@ bool CaptureListEntry::isSimpleSelfCapture() const {
13021302

13031303
CaptureListExpr *CaptureListExpr::create(ASTContext &ctx,
13041304
ArrayRef<CaptureListEntry> captureList,
1305-
ClosureExpr *closureBody) {
1305+
AbstractClosureExpr *closureBody) {
13061306
auto size = totalSizeToAlloc<CaptureListEntry>(captureList.size());
13071307
auto mem = ctx.Allocate(size, alignof(CaptureListExpr));
13081308
auto *expr = ::new(mem) CaptureListExpr(captureList, closureBody);

lib/IDE/Formatting.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ static ClosureExpr *findTrailingClosureFromArgument(Expr *arg) {
140140
if (auto TC = dyn_cast_or_null<ClosureExpr>(arg))
141141
return TC;
142142
if (auto TCL = dyn_cast_or_null<CaptureListExpr>(arg))
143-
return TCL->getClosureBody();
143+
return dyn_cast_or_null<ClosureExpr>(TCL->getClosureBody());
144144
return nullptr;
145145
}
146146

@@ -2488,7 +2488,7 @@ class FormatWalker : public ASTWalker {
24882488
Optional<IndentContext>
24892489
getIndentContextFrom(CaptureListExpr *CL,
24902490
SourceLoc ContextLoc = SourceLoc()) {
2491-
ClosureExpr *CE = CL->getClosureBody();
2491+
AbstractClosureExpr *CE = CL->getClosureBody();
24922492
BraceStmt *BS = CE->getBody();
24932493
if (!CE || !BS)
24942494
return None;
@@ -2503,8 +2503,14 @@ class FormatWalker : public ASTWalker {
25032503
}
25042504

25052505
Optional<IndentContext>
2506-
getIndentContextFrom(ClosureExpr *CE, SourceLoc ContextLoc = SourceLoc(),
2506+
getIndentContextFrom(AbstractClosureExpr *ACE, SourceLoc ContextLoc = SourceLoc(),
25072507
CaptureListExpr *ParentCapture = nullptr) {
2508+
// Explicit capture lists should always have an explicit ClosureExpr as
2509+
// their subexpression.
2510+
auto CE = dyn_cast<ClosureExpr>(ACE);
2511+
if (!CE) {
2512+
return None;
2513+
}
25082514
BraceStmt *BS = CE->getBody();
25092515
if (!BS)
25102516
return None;

lib/IDE/Refactoring.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7315,7 +7315,7 @@ class AsyncConverter : private SourceEntityWalker {
73157315
if (auto Closure = dyn_cast<ClosureExpr>(E)) {
73167316
return Closure;
73177317
} else if (auto CaptureList = dyn_cast<CaptureListExpr>(E)) {
7318-
return CaptureList->getClosureBody();
7318+
return dyn_cast<ClosureExpr>(CaptureList->getClosureBody());
73197319
} else {
73207320
return nullptr;
73217321
}

0 commit comments

Comments
 (0)