Skip to content

Commit 5b50361

Browse files
authored
Merge pull request #75325 from xedin/rdar-131855678-6.0
[6.0][Concurrency] Downgrade mutable captures of `inout` parameters into a…
2 parents 1db020d + 76cd90e commit 5b50361

File tree

5 files changed

+116
-32
lines changed

5 files changed

+116
-32
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4111,10 +4111,13 @@ namespace {
41114111
return false;
41124112
}
41134113

4114-
if (auto param = dyn_cast<ParamDecl>(value)){
4115-
if(param->isInOut()){
4116-
ctx.Diags.diagnose(loc, diag::concurrent_access_of_inout_param, param->getName());
4117-
return true;
4114+
if (auto param = dyn_cast<ParamDecl>(value)) {
4115+
if (param->isInOut()) {
4116+
ctx.Diags
4117+
.diagnose(loc, diag::concurrent_access_of_inout_param,
4118+
param->getName())
4119+
.limitBehaviorUntilSwiftVersion(limit, 6);
4120+
return true;
41184121
}
41194122
}
41204123

test/Concurrency/sendable_checking_captures.swift

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5
2+
// RUN: %target-typecheck-verify-swift -swift-version 5 -strict-concurrency=complete -verify-additional-prefix complete-
3+
4+
class NonSendable {} // expected-complete-note 3{{class 'NonSendable' does not conform to the 'Sendable' protocol}}
5+
6+
func callee(_: @Sendable () -> NonSendable) {}
7+
8+
var testLocalCaptures: Int {
9+
let ns = NonSendable()
10+
11+
@Sendable func localFunc() -> NonSendable {
12+
return ns // expected-complete-warning {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` local function}}
13+
}
14+
15+
callee { return ns } // expected-complete-warning {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure}}
16+
17+
return 3
18+
}
19+
20+
struct Bad {
21+
var c: Int = {
22+
let ns = NonSendable()
23+
callee { return ns } // expected-complete-warning {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure}}
24+
return 3
25+
}()
26+
}
27+
28+
do {
29+
class Test { // expected-complete-note 2 {{class 'Test' does not conform to the 'Sendable' protocol}}
30+
func update() {}
31+
}
32+
33+
func sendable(_: @Sendable () -> Void) {}
34+
35+
@preconcurrency
36+
func sendable_preconcurrency(_: @Sendable () -> Void) {}
37+
38+
func withMutable(_: (inout Test) -> Void) {}
39+
40+
withMutable { test in
41+
sendable {
42+
test.update()
43+
// expected-complete-warning@-1 {{capture of 'test' with non-sendable type 'Test' in a `@Sendable` closure}}
44+
// expected-warning@-2 {{mutable capture of 'inout' parameter 'test' is not allowed in concurrently-executing code}}
45+
}
46+
47+
sendable_preconcurrency {
48+
test.update()
49+
// expected-complete-warning@-1 {{capture of 'test' with non-sendable type 'Test' in a `@Sendable` closure}}
50+
// expected-complete-warning@-2 {{mutable capture of 'inout' parameter 'test' is not allowed in concurrently-executing code}}
51+
}
52+
}
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 6
2+
3+
class NonSendable {} // expected-note 3{{class 'NonSendable' does not conform to the 'Sendable' protocol}}
4+
5+
func callee(_: @Sendable () -> NonSendable) {}
6+
7+
var testLocalCaptures: Int {
8+
let ns = NonSendable()
9+
10+
@Sendable func localFunc() -> NonSendable {
11+
return ns // expected-error {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` local function}}
12+
}
13+
14+
callee { return ns } // expected-error {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure}}
15+
16+
return 3
17+
}
18+
19+
struct Bad {
20+
var c: Int = {
21+
let ns = NonSendable()
22+
callee { return ns } // expected-error {{capture of 'ns' with non-sendable type 'NonSendable' in a `@Sendable` closure}}
23+
return 3
24+
}()
25+
}
26+
27+
do {
28+
class Test { // expected-note 2 {{class 'Test' does not conform to the 'Sendable' protocol}}
29+
func update() {}
30+
}
31+
32+
func sendable(_: @Sendable () -> Void) {}
33+
34+
@preconcurrency
35+
func sendable_preconcurrency(_: @Sendable () -> Void) {}
36+
37+
func withMutable(_: (inout Test) -> Void) {}
38+
39+
withMutable { test in
40+
sendable {
41+
test.update()
42+
// expected-error@-1 {{capture of 'test' with non-sendable type 'Test' in a `@Sendable` closure}}
43+
// expected-error@-2 {{mutable capture of 'inout' parameter 'test' is not allowed in concurrently-executing code}}
44+
}
45+
46+
sendable_preconcurrency {
47+
test.update()
48+
// expected-error@-1 {{capture of 'test' with non-sendable type 'Test' in a `@Sendable` closure}}
49+
// expected-error@-2 {{mutable capture of 'inout' parameter 'test' is not allowed in concurrently-executing code}}
50+
}
51+
}
52+
}

test/Concurrency/taskgroup_cancelAll_from_child.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,18 @@
88

99
@available(SwiftStdlib 5.1, *)
1010
func test_taskGroup_cancelAll() async {
11-
await withTaskGroup(of: Int.self, returning: Void.self) { group in
11+
await withTaskGroup(of: Int.self, returning: Void.self) { group in // expected-note {{parameter 'group' is declared 'inout'}}
1212
group.spawn {
1313
await Task.sleep(3_000_000_000)
1414
let c = Task.isCancelled
1515
print("group task isCancelled: \(c)")
1616
return 0
1717
}
1818

19-
group.spawn {
19+
group.spawn { // expected-error {{escaping closure captures 'inout' parameter 'group'}}
2020
group.cancelAll() //expected-warning{{capture of 'group' with non-sendable type 'TaskGroup<Int>' in a `@Sendable` closure}}
21-
//expected-error@-1{{mutable capture of 'inout' parameter 'group' is not allowed in concurrently-executing code}}
21+
//expected-warning@-1{{mutable capture of 'inout' parameter 'group' is not allowed in concurrently-executing code; this is an error in the Swift 6 language mode}}
22+
// expected-note@-2 {{captured here}}
2223

2324
return 0
2425
}

0 commit comments

Comments
 (0)