Skip to content

Commit c9bb593

Browse files
authored
Merge pull request #36084 from DougGregor/concurrent-value-checking-by-default
Enable ConcurrentValue checking as part of Concurrency mode.
2 parents 9c97456 + ecf36ba commit c9bb593

11 files changed

+25
-22
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,6 @@ namespace swift {
244244
/// Enable experimental concurrency model.
245245
bool EnableExperimentalConcurrency = false;
246246

247-
/// Enable experimental ConcurrentValue checking.
248-
bool EnableExperimentalConcurrentValueChecking = false;
249-
250247
/// Enable experimental flow-sensitive concurrent captures.
251248
bool EnableExperimentalFlowSensitiveConcurrentCaptures = false;
252249

include/swift/Option/FrontendOptions.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,6 @@ def enable_experimental_concurrency :
218218
Flag<["-"], "enable-experimental-concurrency">,
219219
HelpText<"Enable experimental concurrency model">;
220220

221-
def enable_experimental_concurrent_value_checking :
222-
Flag<["-"], "enable-experimental-concurrent-value-checking">,
223-
HelpText<"Enable ConcurrentValue checking">;
224-
225221
def enable_experimental_flow_sensitive_concurrent_captures :
226222
Flag<["-"], "enable-experimental-flow-sensitive-concurrent-captures">,
227223
HelpText<"Enable flow-sensitive concurrent captures">;

lib/Frontend/CompilerInvocation.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
385385

386386
Opts.EnableExperimentalConcurrency |=
387387
Args.hasArg(OPT_enable_experimental_concurrency);
388-
Opts.EnableExperimentalConcurrentValueChecking |=
389-
Args.hasArg(OPT_enable_experimental_concurrent_value_checking);
390388
Opts.EnableExperimentalFlowSensitiveConcurrentCaptures |=
391389
Args.hasArg(OPT_enable_experimental_flow_sensitive_concurrent_captures);
392390

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ bool swift::diagnoseNonConcurrentTypesInReference(
823823
ConcreteDeclRef declRef, const DeclContext *dc, SourceLoc loc,
824824
ConcurrentReferenceKind refKind) {
825825
// Bail out immediately if we aren't supposed to do this checking.
826-
if (!dc->getASTContext().LangOpts.EnableExperimentalConcurrentValueChecking)
826+
if (!dc->getASTContext().LangOpts.EnableExperimentalConcurrency)
827827
return false;
828828

829829
// For functions, check the parameter and result types.
@@ -1118,7 +1118,7 @@ namespace {
11181118
if (!indexExpr || !indexExpr->getType())
11191119
continue;
11201120

1121-
if (ctx.LangOpts.EnableExperimentalConcurrentValueChecking &&
1121+
if (ctx.LangOpts.EnableExperimentalConcurrency &&
11221122
!isConcurrentValueType(getDeclContext(), indexExpr->getType())) {
11231123
ctx.Diags.diagnose(
11241124
component.getLoc(), diag::non_concurrent_keypath_capture,

test/Concurrency/actor_call_implicitly_async.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,22 @@ func blender(_ peeler : () -> Void) {
158158

159159
@OrangeActor func makeSmoothie() async {
160160
await wisk({})
161+
// expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}}
161162
await wisk(1)
163+
// expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}}
162164
await (peelBanana)()
163165
await (((((peelBanana)))))()
164166
await (((wisk)))((wisk)((wisk)(1)))
167+
// expected-warning@-1 3{{cannot pass argument of non-concurrent-value type 'Any' across actors}}
165168

166169
blender((peelBanana)) // expected-error {{global function 'peelBanana()' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}}
167170
await wisk(peelBanana) // expected-error {{global function 'peelBanana()' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}}
171+
// expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}}
168172

169173
await wisk(wisk) // expected-error {{global function 'wisk' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}}
174+
// expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}}
170175
await (((wisk)))(((wisk))) // expected-error {{global function 'wisk' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}}
176+
// expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}}
171177

172178
// expected-warning@+2 {{no calls to 'async' functions occur within 'await' expression}}
173179
// expected-error@+1 {{global function 'wisk' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}}
@@ -205,13 +211,18 @@ actor Calculator {
205211

206212
@OrangeActor func doSomething() async {
207213
let _ = (await bananaAdd(1))(2)
214+
// expected-warning@-1{{cannot call function returning non-concurrent-value type}}
208215
let _ = await (await bananaAdd(1))(2) // expected-warning{{no calls to 'async' functions occur within 'await' expression}}
216+
// expected-warning@-1{{cannot call function returning non-concurrent-value type}}
209217

210218
let calc = Calculator()
211219

212220
let _ = (await calc.addCurried(1))(2)
221+
// expected-warning@-1{{cannot call function returning non-concurrent-value type}}
213222
let _ = await (await calc.addCurried(1))(2) // expected-warning{{no calls to 'async' functions occur within 'await' expression}}
223+
// expected-warning@-1{{cannot call function returning non-concurrent-value type}}
214224

215225
let plusOne = await calc.addCurried(await calc.add(0, 1))
226+
// expected-warning@-1{{cannot call function returning non-concurrent-value type}}
216227
let _ = plusOne(2)
217228
}

test/Concurrency/async_cancellation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func test_cancellation_guard_isCancelled(_ any: Any) async -> PictureData {
1818
return PictureData.value("...")
1919
}
2020

21-
struct SomeFile {
21+
struct SomeFile: ConcurrentValue {
2222
func close() {}
2323
}
2424

test/Concurrency/async_task_groups.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func test_taskGroup_quorum_thenCancel() async {
134134
case yay
135135
case nay
136136
}
137-
struct Follower {
137+
struct Follower: ConcurrentValue {
138138
init(_ name: String) {}
139139
func vote() async throws -> Vote {
140140
// "randomly" vote yes or no
@@ -181,13 +181,13 @@ func test_taskGroup_quorum_thenCancel() async {
181181
_ = await gatherQuorum(followers: [Follower("A"), Follower("B"), Follower("C")])
182182
}
183183

184-
extension Collection {
184+
extension Collection where Self: ConcurrentValue, Element: ConcurrentValue, Self.Index: ConcurrentValue {
185185

186186
/// Just another example of how one might use task groups.
187-
func map<T>(
187+
func map<T: ConcurrentValue>(
188188
parallelism requestedParallelism: Int? = nil/*system default*/,
189189
// ordered: Bool = true, /
190-
_ transform: (Element) async throws -> T
190+
_ transform: @concurrent (Element) async throws -> T
191191
) async throws -> [T] { // TODO: can't use rethrows here, maybe that's just life though; rdar://71479187 (rethrows is a bit limiting with async functions that use task groups)
192192
let defaultParallelism = 2
193193
let parallelism = requestedParallelism ?? defaultParallelism

test/Concurrency/concurrent_value_checking.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-concurrent-value-checking
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
22
// REQUIRES: concurrency
33

44
class NotConcurrent { }

test/Concurrency/concurrent_value_checking_objc.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-concurrent-value-checking
1+
// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency
22

33
// REQUIRES: concurrency
44
// REQUIRES: objc_interop

test/Concurrency/concurrentfunction_capturediagnostics.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ func testCaseTrivialValue4() {
8686
// expected-note @-8 {{capturing use}}
8787
}
8888

89-
class Klass {
89+
class Klass: UnsafeConcurrentValue {
9090
var next: Klass? = nil
9191
}
9292
func inoutUserKlass(_ k: inout Klass) {}
@@ -130,7 +130,7 @@ func testCaseClassInoutField() {
130130
// Non Trivial Value Type //
131131
////////////////////////////
132132

133-
struct NonTrivialValueType {
133+
struct NonTrivialValueType: ConcurrentValue {
134134
var i: Int
135135
var k: Klass? = nil
136136

@@ -182,7 +182,7 @@ protocol MyProt {
182182
var k: Klass? { get set }
183183
}
184184

185-
func testCaseAddressOnlyAllocBoxToStackable<T : MyProt>(i : T) {
185+
func testCaseAddressOnlyAllocBoxToStackable<T : MyProt & ConcurrentValue>(i : T) {
186186
var i2 = i
187187
f {
188188
print(i2.i + 17)
@@ -199,7 +199,7 @@ func testCaseAddressOnlyAllocBoxToStackable<T : MyProt>(i : T) {
199199

200200
// Alloc box to stack can't handle this test case, so show off a bit and make
201201
// sure we can emit a great diagnostic here!
202-
func testCaseAddressOnlyNoAllocBoxToStackable<T : MyProt>(i : T) {
202+
func testCaseAddressOnlyNoAllocBoxToStackable<T : MyProt & ConcurrentValue>(i : T) {
203203
let f2 = F()
204204
var i2 = i
205205
f2.useConcurrent {

test/attr/attr_objc_async.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ actor MyActor {
3434
// CHECK: @objc func doBigJobOrFail(_: Int) async throws -> (AnyObject, Int)
3535
// CHECK-DUMP: func_decl{{.*}}doBigJobOrFail{{.*}}foreign_async=@convention(block) (Optional<AnyObject>, Int, Optional<Error>) -> (),completion_handler_param=1,error_param=2
3636
@objc func doBigJobOrFail(_: Int) async throws -> (AnyObject, Int) { return (self, 0) }
37+
// expected-warning@-1{{cannot call function returning non-concurrent-value type '(AnyObject, Int)' across actors}}
3738

3839
// Actor-isolated entities cannot be exposed to Objective-C.
3940
@objc func synchronousBad() { } // expected-error{{actor-isolated instance method 'synchronousBad()' cannot be @objc}}

0 commit comments

Comments
 (0)