Skip to content

Commit 6463d96

Browse files
committed
Sema: Use AutoClosureExpr again in KeyPathExpr-as-function expansion
Remove the preallocated closure discriminator from KeyPathExpr and go back to expanding them using an AutoClosureExpr inside of a CaptureListExpr now that that's supported. This allows the discriminator to be assigned during type checking without disturbing the indexing of explicit closure literals.
1 parent a35dc48 commit 6463d96

File tree

5 files changed

+18
-49
lines changed

5 files changed

+18
-49
lines changed

include/swift/AST/Expr.h

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5389,10 +5389,6 @@ class KeyPathExpr : public Expr {
53895389
/// a contextual root type.
53905390
bool HasLeadingDot = false;
53915391

5392-
/// When we parse a key path literal, we claim a closure discriminator for it, since it may be used as
5393-
/// a closure value in function type context.
5394-
unsigned ClosureDiscriminator;
5395-
53965392
public:
53975393
/// A single stored component, which will be one of:
53985394
/// - an unresolved DeclNameRef, which has to be type-checked
@@ -5724,12 +5720,11 @@ class KeyPathExpr : public Expr {
57245720

57255721
KeyPathExpr(SourceLoc startLoc, Expr *parsedRoot, Expr *parsedPath,
57265722
SourceLoc endLoc, bool hasLeadingDot, bool isObjC,
5727-
bool isImplicit, unsigned closureDiscriminator);
5723+
bool isImplicit);
57285724

57295725
/// Create a key path with unresolved root and path expressions.
57305726
KeyPathExpr(SourceLoc backslashLoc, Expr *parsedRoot, Expr *parsedPath,
5731-
bool hasLeadingDot, bool isImplicit,
5732-
unsigned closureDiscriminator);
5727+
bool hasLeadingDot, bool isImplicit);
57335728

57345729
/// Create a key path with components.
57355730
KeyPathExpr(ASTContext &ctx, SourceLoc startLoc,
@@ -5740,8 +5735,7 @@ class KeyPathExpr : public Expr {
57405735
/// Create a new parsed Swift key path expression.
57415736
static KeyPathExpr *createParsed(ASTContext &ctx, SourceLoc backslashLoc,
57425737
Expr *parsedRoot, Expr *parsedPath,
5743-
bool hasLeadingDot,
5744-
unsigned closureDiscriminator = AbstractClosureExpr::InvalidDiscriminator);
5738+
bool hasLeadingDot);
57455739

57465740
/// Create a new parsed #keyPath expression.
57475741
static KeyPathExpr *createParsedPoundKeyPath(ASTContext &ctx,
@@ -5836,9 +5830,6 @@ class KeyPathExpr : public Expr {
58365830
/// True if this key path expression has a leading dot.
58375831
bool expectsContextualRoot() const { return HasLeadingDot; }
58385832

5839-
/// Return the discriminator to use if this key path becomes a closure.
5840-
unsigned getClosureDiscriminator() const { return ClosureDiscriminator; }
5841-
58425833
static bool classof(const Expr *E) {
58435834
return E->getKind() == ExprKind::KeyPath;
58445835
}

lib/AST/Expr.cpp

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,24 +2252,21 @@ OpenedArchetypeType *OpenExistentialExpr::getOpenedArchetype() const {
22522252

22532253
KeyPathExpr::KeyPathExpr(SourceLoc startLoc, Expr *parsedRoot,
22542254
Expr *parsedPath, SourceLoc endLoc, bool hasLeadingDot,
2255-
bool isObjC, bool isImplicit,
2256-
unsigned closureDiscriminator)
2255+
bool isObjC, bool isImplicit)
22572256
: Expr(ExprKind::KeyPath, isImplicit), StartLoc(startLoc), EndLoc(endLoc),
22582257
ParsedRoot(parsedRoot), ParsedPath(parsedPath),
2259-
HasLeadingDot(hasLeadingDot), ClosureDiscriminator(closureDiscriminator) {
2258+
HasLeadingDot(hasLeadingDot) {
22602259
assert(!(isObjC && (parsedRoot || parsedPath)) &&
22612260
"Obj-C key paths should only have components");
22622261
Bits.KeyPathExpr.IsObjC = isObjC;
22632262
}
22642263

22652264
KeyPathExpr::KeyPathExpr(SourceLoc backslashLoc, Expr *parsedRoot,
2266-
Expr *parsedPath, bool hasLeadingDot, bool isImplicit,
2267-
unsigned closureDiscriminator)
2265+
Expr *parsedPath, bool hasLeadingDot, bool isImplicit)
22682266
: KeyPathExpr(backslashLoc, parsedRoot, parsedPath,
22692267
parsedPath ? parsedPath->getEndLoc()
22702268
: parsedRoot->getEndLoc(),
2271-
hasLeadingDot, /*isObjC*/ false, isImplicit,
2272-
closureDiscriminator) {
2269+
hasLeadingDot, /*isObjC*/ false, isImplicit) {
22732270
assert((parsedRoot || parsedPath) &&
22742271
"Key path must have either root or path");
22752272
}
@@ -2278,8 +2275,7 @@ KeyPathExpr::KeyPathExpr(ASTContext &ctx, SourceLoc startLoc,
22782275
ArrayRef<Component> components, SourceLoc endLoc,
22792276
bool isObjC, bool isImplicit)
22802277
: KeyPathExpr(startLoc, /*parsedRoot*/ nullptr, /*parsedPath*/ nullptr,
2281-
endLoc, /*hasLeadingDot*/ false, isObjC, isImplicit,
2282-
/*closure discriminator*/ AbstractClosureExpr::InvalidDiscriminator) {
2278+
endLoc, /*hasLeadingDot*/ false, isObjC, isImplicit) {
22832279
assert(!components.empty());
22842280
Components = ctx.AllocateCopy(components);
22852281
}
@@ -2293,11 +2289,9 @@ KeyPathExpr *KeyPathExpr::createParsedPoundKeyPath(
22932289

22942290
KeyPathExpr *KeyPathExpr::createParsed(ASTContext &ctx, SourceLoc backslashLoc,
22952291
Expr *parsedRoot, Expr *parsedPath,
2296-
bool hasLeadingDot,
2297-
unsigned closureDiscriminator) {
2292+
bool hasLeadingDot) {
22982293
return new (ctx) KeyPathExpr(backslashLoc, parsedRoot, parsedPath,
2299-
hasLeadingDot, /*isImplicit*/ false,
2300-
closureDiscriminator);
2294+
hasLeadingDot, /*isImplicit*/ false);
23012295
}
23022296

23032297
KeyPathExpr *KeyPathExpr::createImplicit(ASTContext &ctx,
@@ -2313,8 +2307,7 @@ KeyPathExpr *KeyPathExpr::createImplicit(ASTContext &ctx,
23132307
Expr *parsedRoot, Expr *parsedPath,
23142308
bool hasLeadingDot) {
23152309
return new (ctx) KeyPathExpr(backslashLoc, parsedRoot, parsedPath,
2316-
hasLeadingDot, /*isImplicit*/ true,
2317-
/*closureDiscriminator*/ AbstractClosureExpr::InvalidDiscriminator);
2310+
hasLeadingDot, /*isImplicit*/ true);
23182311
}
23192312

23202313
void

lib/Parse/ParseExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,8 +690,7 @@ ParserResult<Expr> Parser::parseExprKeyPath() {
690690

691691
auto *keypath = KeyPathExpr::createParsed(
692692
Context, backslashLoc, rootResult.getPtrOrNull(),
693-
pathResult.getPtrOrNull(), hasLeadingDot,
694-
CurLocalContext->claimNextClosureDiscriminator());
693+
pathResult.getPtrOrNull(), hasLeadingDot);
695694
return makeParserResult(parseStatus, keypath);
696695
}
697696

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4978,24 +4978,14 @@ namespace {
49784978
// return "{ [$kp$ = \(E)] in $0[keyPath: $kp$] }"
49794979

49804980
auto &ctx = cs.getASTContext();
4981-
auto discriminator = E->getClosureDiscriminator();
4981+
auto discriminator = AutoClosureExpr::InvalidDiscriminator;
49824982

49834983
FunctionType::ExtInfo closureInfo;
49844984
auto closureTy =
49854985
FunctionType::get({FunctionType::Param(baseTy)}, leafTy, closureInfo);
4986-
4987-
ClosureExpr *closure = new (ctx)
4988-
ClosureExpr(DeclAttributes(),
4989-
SourceRange(),
4990-
/*captured self*/ nullptr,
4991-
/*params*/ nullptr,
4992-
SourceLoc(),
4993-
SourceLoc(),
4994-
SourceLoc(),
4995-
SourceLoc(),
4996-
/*explicit result type*/ nullptr,
4997-
discriminator,
4998-
dc);
4986+
auto closure = new (ctx)
4987+
AutoClosureExpr(/*set body later*/nullptr, leafTy,
4988+
discriminator, dc);
49994989

50004990
auto param = new (ctx) ParamDecl(
50014991
SourceLoc(),
@@ -5054,14 +5044,10 @@ namespace {
50545044
E->getStartLoc(), outerParamRef, E->getEndLoc(),
50555045
leafTy, /*implicit=*/true);
50565046
cs.cacheType(application);
5057-
5058-
auto returnStmt = new (ctx) ReturnStmt(SourceLoc(), application);
5059-
auto bodyStmt = BraceStmt::create(ctx,
5060-
SourceLoc(), ASTNode(returnStmt), SourceLoc());
50615047

50625048
// Finish up the inner closure.
50635049
closure->setParameterList(ParameterList::create(ctx, {param}));
5064-
closure->setBody(bodyStmt, /*singleExpr*/ true);
5050+
closure->setBody(application);
50655051
closure->setType(closureTy);
50665052
cs.cacheType(closure);
50675053

test/SILGen/closure_literal_reabstraction.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ func reabstractCaptureListExprArgument() {
1616
}
1717

1818
// CHECK-LABEL: sil {{.*}} @{{.*}}reabstractKeyPathFunctionArgument
19-
// CHECK: [[CLOSURE_FN:%.*]] = function_ref {{.*}}U_
19+
// CHECK: [[CLOSURE_FN:%.*]] = function_ref {{.*}}u_
2020
// CHECK: [[KP_ARG:%.*]] = copy_value {{.*}} $KeyPath
2121
// CHECK: [[CLOSURE:%.*]] = partial_apply {{.*}}[[CLOSURE_FN]]([[KP_ARG]])
2222
// CHECK: [[CLOSURE_NE:%.*]] = convert_escape_to_noescape {{.*}} [[CLOSURE]]

0 commit comments

Comments
 (0)