Skip to content

Commit df62d49

Browse files
authored
Merge pull request swiftlang#75731 from kavon/closure-parameter-ownership-infer
Ownership: infer from contextual parameter's type
2 parents e2c9541 + 6331381 commit df62d49

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11835,10 +11835,19 @@ bool ConstraintSystem::resolveClosure(TypeVariableType *typeVar,
1183511835
if (contextualParam->isIsolated() && !flags.isIsolated() && paramDecl)
1183611836
isolatedParams.insert(paramDecl);
1183711837

11838+
// Carry-over the ownership specifier from the contextual parameter.
11839+
auto paramOwnership =
11840+
contextualParam->getParameterFlags().getOwnershipSpecifier();
11841+
11842+
// `sending` is already carried over; skip this related ownership kind.
11843+
if (paramOwnership == ParamSpecifier::ImplicitlyCopyableConsuming)
11844+
paramOwnership = flags.getOwnershipSpecifier();
11845+
1183811846
param = param.withFlags(flags.withInOut(contextualParam->isInOut())
1183911847
.withVariadic(contextualParam->isVariadic())
1184011848
.withIsolated(contextualParam->isIsolated())
11841-
.withSending(contextualParam->isSending()));
11849+
.withSending(contextualParam->isSending())
11850+
.withOwnershipSpecifier(paramOwnership));
1184211851
}
1184311852
}
1184411853

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: %target-swift-frontend %s -emit-sil -verify
2+
3+
struct NC: ~Copyable {
4+
func borrow() {}
5+
consuming func consume() {}
6+
mutating func mutate () {}
7+
}
8+
9+
struct Box<Wrapped: ~Copyable> {
10+
consuming func map(_ transform: (consuming Wrapped)->Void) { }
11+
}
12+
13+
struct Tree: ~Copyable {
14+
static func insert(_ box: consuming Box<Self>) {
15+
box.map { x in x.insert() }
16+
}
17+
18+
consuming func insert() { }
19+
}
20+
21+
func withConsuming(_ body: (consuming NC) -> Void) {
22+
body(NC())
23+
}
24+
25+
func withBorrowing(_ body: (borrowing NC) -> Void) {
26+
body(NC())
27+
}
28+
29+
func withMutating(_ body: (inout NC) -> Void) {
30+
var nc = NC()
31+
body(&nc)
32+
}
33+
34+
func withShared(_ body: (__shared NC) -> Void) {
35+
body(NC())
36+
}
37+
38+
func withOwned(_ body: (__owned NC) -> Void) {
39+
body(NC())
40+
}
41+
42+
withMutating { nc in
43+
nc.mutate()
44+
}
45+
46+
withConsuming { nc in
47+
nc.consume()
48+
}
49+
50+
withBorrowing { // expected-error {{'$0' is borrowed and cannot be consumed}}
51+
$0.borrow()
52+
$0.consume() // expected-note {{consumed here}}
53+
}
54+
55+
withShared { // expected-error {{'$0' is borrowed and cannot be consumed}}
56+
$0.borrow()
57+
$0.consume() // expected-note {{consumed here}}
58+
}
59+
60+
withOwned {
61+
$0.consume()
62+
}
63+
64+
do {
65+
let clos: (consuming NC) -> Void = {
66+
$0.consume()
67+
}
68+
clos(NC())
69+
}

0 commit comments

Comments
 (0)