Skip to content

Commit fcbe559

Browse files
authored
Merge pull request #70871 from hborla/fix-complete-concurrency-flags
[Concurrency] Promote `StrictConcurrency` to an upcoming feature flag.
2 parents c8fe36d + d37b976 commit fcbe559

13 files changed

+43
-76
lines changed

include/swift/Basic/Features.def

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(Extern, 0, "@_extern")
117117

118118
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
119119
UPCOMING_FEATURE(ForwardTrailingClosures, 286, 6)
120-
UPCOMING_FEATURE(CompleteConcurrency, 0337, 6)
120+
UPCOMING_FEATURE(StrictConcurrency, 0337, 6)
121121
UPCOMING_FEATURE(BareSlashRegexLiterals, 354, 6)
122122
UPCOMING_FEATURE(DeprecateApplicationMain, 383, 6)
123123
UPCOMING_FEATURE(ImportObjcForwardDeclarations, 384, 6)
@@ -216,9 +216,6 @@ EXPERIMENTAL_FEATURE(ReferenceBindings, true)
216216
/// Enable the explicit 'import Builtin' and allow Builtin usage.
217217
EXPERIMENTAL_FEATURE(BuiltinModule, true)
218218

219-
// Enable strict concurrency.
220-
EXPERIMENTAL_FEATURE(StrictConcurrency, true)
221-
222219
/// Region Based Isolation testing using the TransferNonSendable pass
223220
EXPERIMENTAL_FEATURE(RegionBasedIsolation, false)
224221

lib/AST/ASTPrinter.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3483,10 +3483,6 @@ static bool usesFeatureForwardTrailingClosures(Decl *decl) {
34833483
return false;
34843484
}
34853485

3486-
static bool usesFeatureCompleteConcurrency(Decl *decl) {
3487-
return false;
3488-
}
3489-
34903486
static bool usesFeatureBareSlashRegexLiterals(Decl *decl) {
34913487
return false;
34923488
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -808,20 +808,10 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
808808
if (value.startswith("StrictConcurrency")) {
809809
auto decomposed = value.split("=");
810810
if (decomposed.first == "StrictConcurrency") {
811-
bool handled;
812811
if (decomposed.second == "") {
813812
Opts.StrictConcurrencyLevel = StrictConcurrency::Complete;
814-
handled = true;
815813
} else if (auto level = parseStrictConcurrency(decomposed.second)) {
816814
Opts.StrictConcurrencyLevel = *level;
817-
handled = true;
818-
} else {
819-
handled = false;
820-
}
821-
822-
if (handled) {
823-
Opts.enableFeature(Feature::StrictConcurrency);
824-
continue;
825815
}
826816
}
827817
}
@@ -876,14 +866,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
876866
Opts.enableFeature(*feature);
877867
}
878868

879-
// CompleteConcurrency enables all data-race safety upcoming features.
880-
if (Opts.hasFeature(Feature::CompleteConcurrency)) {
881-
Opts.StrictConcurrencyLevel = StrictConcurrency::Complete;
882-
Opts.enableFeature(Feature::DisableOutwardActorInference);
883-
Opts.enableFeature(Feature::IsolatedDefaultValues);
884-
Opts.enableFeature(Feature::GlobalConcurrency);
885-
}
886-
887869
// Map historical flags over to experimental features. We do this for all
888870
// compilers because that's how existing experimental feature flags work.
889871
if (Args.hasArg(OPT_enable_experimental_static_assert))
@@ -1001,7 +983,7 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
1001983
"-warn-swift3-objc-inference-complete");
1002984

1003985
// Swift 6+ uses the strictest concurrency level.
1004-
if (Opts.isSwiftVersionAtLeast(6)) {
986+
if (Opts.hasFeature(Feature::StrictConcurrency)) {
1005987
Opts.StrictConcurrencyLevel = StrictConcurrency::Complete;
1006988
} else if (const Arg *A = Args.getLastArg(OPT_strict_concurrency)) {
1007989
if (auto value = parseStrictConcurrency(A->getValue()))
@@ -1012,17 +994,24 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
1012994

1013995
} else if (Args.hasArg(OPT_warn_concurrency)) {
1014996
Opts.StrictConcurrencyLevel = StrictConcurrency::Complete;
1015-
} else if (Opts.hasFeature(Feature::CompleteConcurrency) ||
1016-
Opts.hasFeature(Feature::StrictConcurrency)) {
1017-
// Already set above.
1018997
} else {
1019998
// Default to minimal checking in Swift 5.x.
1020-
Opts.StrictConcurrencyLevel = StrictConcurrency::Minimal;
999+
}
1000+
1001+
// Make sure StrictConcurrency, StrictConcurrency=complete and
1002+
// -strict-concurrency=complete all mean the same thing.
1003+
//
1004+
// The compiler implementation should standardize on StrictConcurrencyLevel,
1005+
// but if there is any check for `Feature::StrictConcurrency`, the result
1006+
// should be the same regardless of which flag was used to enable it.
1007+
if (Opts.StrictConcurrencyLevel == StrictConcurrency::Complete) {
1008+
Opts.enableFeature(Feature::StrictConcurrency);
10211009
}
10221010

10231011
// StrictConcurrency::Complete enables all data-race safety features.
10241012
if (Opts.StrictConcurrencyLevel == StrictConcurrency::Complete) {
10251013
Opts.enableFeature(Feature::IsolatedDefaultValues);
1014+
Opts.enableFeature(Feature::GlobalConcurrency);
10261015
}
10271016

10281017
Opts.WarnImplicitOverrides =
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
struct Foo {
2-
static let member = Bar()
2+
static let member = Bar() // expected-complete-warning {{static property 'member' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6}}
33
}

test/Concurrency/actor_inout_isolation.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ actor TestActor {
4343
}
4444

4545
@available(SwiftStdlib 5.1, *)
46-
func modifyAsynchronously(_ foo: inout Int) async { foo += 1 }
46+
@Sendable func modifyAsynchronously(_ foo: inout Int) async { foo += 1 }
4747
@available(SwiftStdlib 5.1, *)
4848
enum Container {
4949
static let modifyAsyncValue = modifyAsynchronously
@@ -321,4 +321,4 @@ actor ProtectDictionary {
321321
// expected-warning@-1 {{cannot call mutating async function 'mutate()' on actor-isolated property 'dict'; this is an error in Swift 6}}
322322
// expected-targeted-complete-warning@-2 {{passing argument of non-sendable type 'inout Optional<Int>' outside of actor-isolated context may introduce data races}}
323323
}
324-
}
324+
}

test/Concurrency/actor_isolation.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
import OtherActors // expected-warning{{add '@preconcurrency' to suppress 'Sendable'-related warnings from module 'OtherActors'}}{{1-1=@preconcurrency }}
1212

1313
let immutableGlobal: String = "hello"
14+
15+
// expected-warning@+2 {{var 'mutableGlobal' is not concurrency-safe because it is non-isolated global shared mutable state; this is an error in Swift 6}}
16+
// expected-note@+1 {{isolate 'mutableGlobal' to a global actor, or convert it to a 'let' constant and conform it to 'Sendable'}}
1417
var mutableGlobal: String = "can't touch this" // expected-note 5{{var declared here}}
1518

1619
@available(SwiftStdlib 5.1, *)

test/Concurrency/complete_concurrency.swift

Lines changed: 0 additions & 30 deletions
This file was deleted.

test/Concurrency/concurrency_warnings.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,19 @@ class GlobalCounter {
88
var counter: Int = 0
99
}
1010

11-
let rs = GlobalCounter()
12-
var globalInt = 17 // expected-note 2{{var declared here}}
11+
let rs = GlobalCounter() // expected-warning {{let 'rs' is not concurrency-safe because it is not either conforming to 'Sendable' or isolated to a global actor; this is an error in Swift 6}}
12+
13+
var globalInt = 17 // expected-warning {{var 'globalInt' is not concurrency-safe because it is non-isolated global shared mutable state; this is an error in Swift 6}}
14+
// expected-note@-1 {{isolate 'globalInt' to a global actor, or convert it to a 'let' constant and conform it to 'Sendable'}}
15+
// expected-note@-2 2{{var declared here}}
16+
1317

1418
class MyError: Error { // expected-warning{{non-final class 'MyError' cannot conform to 'Sendable'; use '@unchecked Sendable'}}
1519
var storage = 0 // expected-warning{{stored property 'storage' of 'Sendable'-conforming class 'MyError' is mutable}}
1620
}
1721

1822
func testWarnings() {
19-
_ = rs // TODO: warn here
23+
_ = rs
2024
_ = globalInt // expected-warning{{reference to var 'globalInt' is not concurrency-safe because it involves shared mutable state}}
2125
globalInt += 1 // expected-warning{{reference to var 'globalInt' is not concurrency-safe because it involves shared mutable state}}
2226
}

test/Concurrency/concurrent_value_checking.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,8 @@ typealias CF = @Sendable () -> NotConcurrent?
271271
typealias BadGenericCF<T> = @Sendable () -> T?
272272
typealias GoodGenericCF<T: Sendable> = @Sendable () -> T? // okay
273273

274-
var concurrentFuncVar: (@Sendable (NotConcurrent) -> Void)? = nil
274+
var concurrentFuncVar: (@Sendable (NotConcurrent) -> Void)? = nil // expected-warning{{var 'concurrentFuncVar' is not concurrency-safe because it is non-isolated global shared mutable state; this is an error in Swift 6}}
275+
// expected-note@-1 {{isolate 'concurrentFuncVar' to a global actor, or convert it to a 'let' constant and conform it to 'Sendable'}}
275276

276277
// ----------------------------------------------------------------------
277278
// Sendable restriction on @Sendable closures.

test/Concurrency/experimental_feature_strictconcurrency.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %target-swift-frontend -disable-availability-checking -enable-experimental-feature StrictConcurrency -emit-sil -o /dev/null -verify %s
22
// RUN: %target-swift-frontend -disable-availability-checking -enable-experimental-feature StrictConcurrency=complete -emit-sil -o /dev/null -verify %s
3-
// RUN: %target-swift-frontend -disable-availability-checking -enable-experimental-feature StrictConcurrency=complete -emit-sil -o /dev/null -verify -verify-additional-prefix region-isolation- -enable-experimental-feature RegionBasedIsolation %s
3+
// RUN: %target-swift-frontend -disable-availability-checking -enable-upcoming-feature StrictConcurrency -emit-sil -o /dev/null -verify %s
4+
// RUN: %target-swift-frontend -disable-availability-checking -enable-upcoming-feature StrictConcurrency -emit-sil -o /dev/null -verify -verify-additional-prefix region-isolation- -enable-experimental-feature RegionBasedIsolation %s
45

56
// REQUIRES: concurrency
67
// REQUIRES: asserts

0 commit comments

Comments
 (0)