Skip to content

Commit d06f7b1

Browse files
committed
SILGen: Apply function_conversion peephole to CaptureListExprs.
Don't let a capture list suppress the reabstraction peephole when a closure literal appears in a context with a function conversion.
1 parent c6b6787 commit d06f7b1

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

lib/SILGen/SILGenExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1804,7 +1804,7 @@ RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
18041804
// TODO: Move this up when we can emit closures directly with C calling
18051805
// convention.
18061806
auto subExpr = e->getSubExpr()->getSemanticsProvidingExpr();
1807-
if (isa<AbstractClosureExpr>(subExpr)
1807+
if ((isa<AbstractClosureExpr>(subExpr) || isa<CaptureListExpr>(subExpr))
18081808
&& canPeepholeLiteralClosureConversion(subExpr->getType(),
18091809
e->getType())) {
18101810
// If we're emitting into a context with a preferred abstraction pattern

lib/SILGen/SILGenPoly.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
//
8383
//===----------------------------------------------------------------------===//
8484

85+
#define DEBUG_TYPE "silgen-poly"
8586
#include "ExecutorBreadcrumb.h"
8687
#include "Initialization.h"
8788
#include "LValue.h"
@@ -3055,6 +3056,24 @@ static ManagedValue createThunk(SILGenFunction &SGF,
30553056
auto substSourceType = fn.getType().castTo<SILFunctionType>();
30563057
auto substExpectedType = expectedTL.getLoweredType().castTo<SILFunctionType>();
30573058

3059+
LLVM_DEBUG(llvm::dbgs() << "=== Generating reabstraction thunk from:\n";
3060+
substSourceType.dump(llvm::dbgs());
3061+
llvm::dbgs() << "\n to:\n";
3062+
substExpectedType.dump(llvm::dbgs());
3063+
llvm::dbgs() << "\n for source location:\n";
3064+
if (auto d = loc.getAsASTNode<Decl>()) {
3065+
d->dump(llvm::dbgs());
3066+
} else if (auto e = loc.getAsASTNode<Expr>()) {
3067+
e->dump(llvm::dbgs());
3068+
} else if (auto s = loc.getAsASTNode<Stmt>()) {
3069+
s->dump(llvm::dbgs());
3070+
} else if (auto p = loc.getAsASTNode<Pattern>()) {
3071+
p->dump(llvm::dbgs());
3072+
} else {
3073+
loc.dump();
3074+
}
3075+
llvm::dbgs() << "\n");
3076+
30583077
// Apply substitutions in the source and destination types, since the thunk
30593078
// doesn't change because of different function representations.
30603079
CanSILFunctionType sourceType;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
3+
func gen<T, U>(f: (T) throws -> U) {}
4+
5+
struct Butt {
6+
var x: Int
7+
}
8+
9+
// CHECK-LABEL: sil {{.*}} @{{.*}}reabstractCaptureListExprArgument
10+
// CHECK: [[CLOSURE_FN:%.*]] = function_ref {{.*}}U_
11+
// CHECK: [[CLOSURE:%.*]] = partial_apply {{.*}}[[CLOSURE_FN]]
12+
// CHECK: [[CLOSURE_NE:%.*]] = convert_escape_to_noescape {{.*}} [[CLOSURE]]
13+
// CHECK: apply {{.*}}<Int, Int>([[CLOSURE_NE]])
14+
func reabstractCaptureListExprArgument() {
15+
gen(f: {[x = 42] y in x + y })
16+
}
17+
18+
// CHECK-LABEL: sil {{.*}} @{{.*}}reabstractKeyPathFunctionArgument
19+
// CHECK: [[CLOSURE_FN:%.*]] = function_ref {{.*}}U_
20+
// CHECK: [[KP_ARG:%.*]] = copy_value {{.*}} $KeyPath
21+
// CHECK: [[CLOSURE:%.*]] = partial_apply {{.*}}[[CLOSURE_FN]]([[KP_ARG]])
22+
// CHECK: [[CLOSURE_NE:%.*]] = convert_escape_to_noescape {{.*}} [[CLOSURE]]
23+
// CHECK: apply {{.*}}<Butt, Int>([[CLOSURE_NE]])
24+
func reabstractKeyPathFunctionArgument() {
25+
gen(f: \Butt.x)
26+
}

0 commit comments

Comments
 (0)