diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 106e452882d..7d3b85b1802 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -244,9 +244,6 @@ namespace swift { /// Enable experimental concurrency model. bool EnableExperimentalConcurrency = false; - /// Enable experimental ConcurrentValue checking. - bool EnableExperimentalConcurrentValueChecking = false; - /// Enable experimental flow-sensitive concurrent captures. bool EnableExperimentalFlowSensitiveConcurrentCaptures = false; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 855a104fc60..5127e871b36 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -218,10 +218,6 @@ def enable_experimental_concurrency : Flag<["-"], "enable-experimental-concurrency">, HelpText<"Enable experimental concurrency model">; -def enable_experimental_concurrent_value_checking : - Flag<["-"], "enable-experimental-concurrent-value-checking">, - HelpText<"Enable ConcurrentValue checking">; - def enable_experimental_flow_sensitive_concurrent_captures : Flag<["-"], "enable-experimental-flow-sensitive-concurrent-captures">, HelpText<"Enable flow-sensitive concurrent captures">; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index ca14a6c0020..17118ea1326 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -385,8 +385,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.EnableExperimentalConcurrency |= Args.hasArg(OPT_enable_experimental_concurrency); - Opts.EnableExperimentalConcurrentValueChecking |= - Args.hasArg(OPT_enable_experimental_concurrent_value_checking); Opts.EnableExperimentalFlowSensitiveConcurrentCaptures |= Args.hasArg(OPT_enable_experimental_flow_sensitive_concurrent_captures); diff --git a/lib/Sema/TypeCheckConcurrency.cpp b/lib/Sema/TypeCheckConcurrency.cpp index ab419c64e8b..2d49e458d05 100644 --- a/lib/Sema/TypeCheckConcurrency.cpp +++ b/lib/Sema/TypeCheckConcurrency.cpp @@ -823,7 +823,7 @@ bool swift::diagnoseNonConcurrentTypesInReference( ConcreteDeclRef declRef, const DeclContext *dc, SourceLoc loc, ConcurrentReferenceKind refKind) { // Bail out immediately if we aren't supposed to do this checking. - if (!dc->getASTContext().LangOpts.EnableExperimentalConcurrentValueChecking) + if (!dc->getASTContext().LangOpts.EnableExperimentalConcurrency) return false; // For functions, check the parameter and result types. @@ -1118,7 +1118,7 @@ namespace { if (!indexExpr || !indexExpr->getType()) continue; - if (ctx.LangOpts.EnableExperimentalConcurrentValueChecking && + if (ctx.LangOpts.EnableExperimentalConcurrency && !isConcurrentValueType(getDeclContext(), indexExpr->getType())) { ctx.Diags.diagnose( component.getLoc(), diag::non_concurrent_keypath_capture, diff --git a/test/Concurrency/actor_call_implicitly_async.swift b/test/Concurrency/actor_call_implicitly_async.swift index 6042a50e16d..4405808894d 100644 --- a/test/Concurrency/actor_call_implicitly_async.swift +++ b/test/Concurrency/actor_call_implicitly_async.swift @@ -158,16 +158,22 @@ func blender(_ peeler : () -> Void) { @OrangeActor func makeSmoothie() async { await wisk({}) + // expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}} await wisk(1) + // expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}} await (peelBanana)() await (((((peelBanana)))))() await (((wisk)))((wisk)((wisk)(1))) + // expected-warning@-1 3{{cannot pass argument of non-concurrent-value type 'Any' across actors}} blender((peelBanana)) // expected-error {{global function 'peelBanana()' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}} await wisk(peelBanana) // expected-error {{global function 'peelBanana()' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}} + // expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}} await wisk(wisk) // expected-error {{global function 'wisk' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}} + // expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}} await (((wisk)))(((wisk))) // expected-error {{global function 'wisk' isolated to global actor 'BananaActor' can not be referenced from different global actor 'OrangeActor'}} + // expected-warning@-1{{cannot pass argument of non-concurrent-value type 'Any' across actors}} // expected-warning@+2 {{no calls to 'async' functions occur within 'await' expression}} // 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 { @OrangeActor func doSomething() async { let _ = (await bananaAdd(1))(2) + // expected-warning@-1{{cannot call function returning non-concurrent-value type}} let _ = await (await bananaAdd(1))(2) // expected-warning{{no calls to 'async' functions occur within 'await' expression}} + // expected-warning@-1{{cannot call function returning non-concurrent-value type}} let calc = Calculator() let _ = (await calc.addCurried(1))(2) + // expected-warning@-1{{cannot call function returning non-concurrent-value type}} let _ = await (await calc.addCurried(1))(2) // expected-warning{{no calls to 'async' functions occur within 'await' expression}} + // expected-warning@-1{{cannot call function returning non-concurrent-value type}} let plusOne = await calc.addCurried(await calc.add(0, 1)) + // expected-warning@-1{{cannot call function returning non-concurrent-value type}} let _ = plusOne(2) } diff --git a/test/Concurrency/async_cancellation.swift b/test/Concurrency/async_cancellation.swift index aaaf35b0af9..50b6ff331c9 100644 --- a/test/Concurrency/async_cancellation.swift +++ b/test/Concurrency/async_cancellation.swift @@ -18,7 +18,7 @@ func test_cancellation_guard_isCancelled(_ any: Any) async -> PictureData { return PictureData.value("...") } -struct SomeFile { +struct SomeFile: ConcurrentValue { func close() {} } diff --git a/test/Concurrency/async_task_groups.swift b/test/Concurrency/async_task_groups.swift index fafdb99848f..13a03b0bb47 100644 --- a/test/Concurrency/async_task_groups.swift +++ b/test/Concurrency/async_task_groups.swift @@ -134,7 +134,7 @@ func test_taskGroup_quorum_thenCancel() async { case yay case nay } - struct Follower { + struct Follower: ConcurrentValue { init(_ name: String) {} func vote() async throws -> Vote { // "randomly" vote yes or no @@ -181,13 +181,13 @@ func test_taskGroup_quorum_thenCancel() async { _ = await gatherQuorum(followers: [Follower("A"), Follower("B"), Follower("C")]) } -extension Collection { +extension Collection where Self: ConcurrentValue, Element: ConcurrentValue, Self.Index: ConcurrentValue { /// Just another example of how one might use task groups. - func map( + func map( parallelism requestedParallelism: Int? = nil/*system default*/, // ordered: Bool = true, / - _ transform: (Element) async throws -> T + _ transform: @concurrent (Element) async throws -> T ) 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) let defaultParallelism = 2 let parallelism = requestedParallelism ?? defaultParallelism diff --git a/test/Concurrency/concurrent_value_checking.swift b/test/Concurrency/concurrent_value_checking.swift index ada9fbb3de2..05ebdfa0213 100644 --- a/test/Concurrency/concurrent_value_checking.swift +++ b/test/Concurrency/concurrent_value_checking.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-concurrent-value-checking +// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency // REQUIRES: concurrency class NotConcurrent { } diff --git a/test/Concurrency/concurrent_value_checking_objc.swift b/test/Concurrency/concurrent_value_checking_objc.swift index 4d360b6f0c1..3a8aa81bf89 100644 --- a/test/Concurrency/concurrent_value_checking_objc.swift +++ b/test/Concurrency/concurrent_value_checking_objc.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency -enable-experimental-concurrent-value-checking +// RUN: %target-typecheck-verify-swift -enable-experimental-concurrency // REQUIRES: concurrency // REQUIRES: objc_interop diff --git a/test/Concurrency/concurrentfunction_capturediagnostics.swift b/test/Concurrency/concurrentfunction_capturediagnostics.swift index 7178b3e0ea3..513461a29b0 100644 --- a/test/Concurrency/concurrentfunction_capturediagnostics.swift +++ b/test/Concurrency/concurrentfunction_capturediagnostics.swift @@ -86,7 +86,7 @@ func testCaseTrivialValue4() { // expected-note @-8 {{capturing use}} } -class Klass { +class Klass: UnsafeConcurrentValue { var next: Klass? = nil } func inoutUserKlass(_ k: inout Klass) {} @@ -130,7 +130,7 @@ func testCaseClassInoutField() { // Non Trivial Value Type // //////////////////////////// -struct NonTrivialValueType { +struct NonTrivialValueType: ConcurrentValue { var i: Int var k: Klass? = nil @@ -182,7 +182,7 @@ protocol MyProt { var k: Klass? { get set } } -func testCaseAddressOnlyAllocBoxToStackable(i : T) { +func testCaseAddressOnlyAllocBoxToStackable(i : T) { var i2 = i f { print(i2.i + 17) @@ -199,7 +199,7 @@ func testCaseAddressOnlyAllocBoxToStackable(i : T) { // Alloc box to stack can't handle this test case, so show off a bit and make // sure we can emit a great diagnostic here! -func testCaseAddressOnlyNoAllocBoxToStackable(i : T) { +func testCaseAddressOnlyNoAllocBoxToStackable(i : T) { let f2 = F() var i2 = i f2.useConcurrent { diff --git a/test/attr/attr_objc_async.swift b/test/attr/attr_objc_async.swift index 2724d258e78..d0b068fc925 100644 --- a/test/attr/attr_objc_async.swift +++ b/test/attr/attr_objc_async.swift @@ -34,6 +34,7 @@ actor MyActor { // CHECK: @objc func doBigJobOrFail(_: Int) async throws -> (AnyObject, Int) // CHECK-DUMP: func_decl{{.*}}doBigJobOrFail{{.*}}foreign_async=@convention(block) (Optional, Int, Optional) -> (),completion_handler_param=1,error_param=2 @objc func doBigJobOrFail(_: Int) async throws -> (AnyObject, Int) { return (self, 0) } + // expected-warning@-1{{cannot call function returning non-concurrent-value type '(AnyObject, Int)' across actors}} // Actor-isolated entities cannot be exposed to Objective-C. @objc func synchronousBad() { } // expected-error{{actor-isolated instance method 'synchronousBad()' cannot be @objc}}