Skip to content

Commit b20f3c4

Browse files
authored
Merge pull request #66823 from jckarter/nonescaping-closure-conversion-moveonly-checker-5.9
[5.9] MoveOnlyChecker: Look through `convert_function` of nonescaping closures.
2 parents a91cd6e + fadf5d4 commit b20f3c4

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,11 @@ static bool findNonEscapingPartialApplyUses(PartialApplyInst *pai,
910910
//
911911
// We have this separately from the other look through sections so that
912912
// we can make it clearer what we are doing here.
913-
isa<PartialApplyInst>(user)) {
913+
isa<PartialApplyInst>(user) ||
914+
// Likewise with convert_function. Any valid function conversion that
915+
// doesn't prevent stack promotion of the closure must retain the
916+
// invariants on its transitive uses.
917+
isa<ConvertFunctionInst>(user)) {
914918
for (auto *use : cast<SingleValueInstruction>(user)->getUses())
915919
worklist.push_back(use);
916920
continue;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %target-swift-frontend -emit-sil -verify %s
2+
3+
// rdar://111060678
4+
5+
protocol P {
6+
func doStuff() throws
7+
}
8+
9+
struct A: ~Copyable {
10+
let b = B()
11+
12+
consuming func f(_ p: some P) throws -> B {
13+
// Passing the closure here undergoes a SIL-level function conversion
14+
// from the concrete type `() -> Void` to `<T> () throws -> T`.
15+
try b.takeClosure {
16+
try b.takeP(p)
17+
}
18+
return B()
19+
}
20+
}
21+
22+
struct B {
23+
func takeClosure<T>(_ f: () throws -> T) throws -> T { try f() }
24+
func takeP(_: some P) throws {}
25+
}

0 commit comments

Comments
 (0)