Enable ConcurrentValue checking as part of Concurrency mode.

Drop the separate flag guarding this checking.
This commit is contained in:
Doug Gregor
2021-02-22 00:29:56 -08:00
parent 65d6af6b98
commit ecf36ba6bc
11 changed files with 25 additions and 22 deletions

View File

@@ -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;

View File

@@ -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">;

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)
}

View File

@@ -18,7 +18,7 @@ func test_cancellation_guard_isCancelled(_ any: Any) async -> PictureData {
return PictureData.value("...")
}
struct SomeFile {
struct SomeFile: ConcurrentValue {
func close() {}
}

View File

@@ -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<T>(
func map<T: ConcurrentValue>(
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

View File

@@ -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 { }

View File

@@ -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

View File

@@ -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<T : MyProt>(i : T) {
func testCaseAddressOnlyAllocBoxToStackable<T : MyProt & ConcurrentValue>(i : T) {
var i2 = i
f {
print(i2.i + 17)
@@ -199,7 +199,7 @@ func testCaseAddressOnlyAllocBoxToStackable<T : MyProt>(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<T : MyProt>(i : T) {
func testCaseAddressOnlyNoAllocBoxToStackable<T : MyProt & ConcurrentValue>(i : T) {
let f2 = F()
var i2 = i
f2.useConcurrent {

View File

@@ -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<AnyObject>, Int, Optional<Error>) -> (),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}}