Skip to content

Commit e47a66c

Browse files
committed
[Concurrency] Enable IsolatedDefaultValues under strict concurrency checking.
1 parent 5ac839b commit e47a66c

File tree

5 files changed

+37
-23
lines changed

5 files changed

+37
-23
lines changed

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,6 +1020,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
10201020
Opts.StrictConcurrencyLevel = StrictConcurrency::Minimal;
10211021
}
10221022

1023+
// StrictConcurrency::Complete enables all data-race safety features.
1024+
if (Opts.StrictConcurrencyLevel == StrictConcurrency::Complete) {
1025+
Opts.enableFeature(Feature::IsolatedDefaultValues);
1026+
}
1027+
10231028
Opts.WarnImplicitOverrides =
10241029
Args.hasArg(OPT_warn_implicit_overrides);
10251030

lib/Sema/CodeSynthesis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
337337
ctor->setSynthesized();
338338
ctor->setAccess(accessLevel);
339339

340-
if (ctx.LangOpts.hasFeature(Feature::IsolatedDefaultValues)) {
340+
if (ctx.LangOpts.hasFeature(Feature::IsolatedDefaultValues) &&
341+
!decl->isActor()) {
341342
// If any of the type's actor-isolated properties:
342343
// 1. Have non-Sendable type, or
343344
// 2. Have an isolated initial value

test/Concurrency/actor_isolation.swift

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -765,15 +765,14 @@ actor LocalFunctionIsolatedActor {
765765
@available(SwiftStdlib 5.1, *)
766766
actor LazyActor {
767767
var v: Int = 0
768-
// expected-note@-1 6 {{property declared here}}
769768

770769
let l: Int = 0
771770

772771
lazy var l11: Int = { v }()
773772
lazy var l12: Int = v
774773
lazy var l13: Int = { self.v }()
775774
lazy var l14: Int = self.v
776-
lazy var l15: Int = { [unowned self] in self.v }() // expected-error{{actor-isolated property 'v' can not be referenced from a non-isolated context}}
775+
lazy var l15: Int = { [unowned self] in self.v }()
777776

778777
lazy var l21: Int = { l }()
779778
lazy var l22: Int = l
@@ -782,15 +781,15 @@ actor LazyActor {
782781
lazy var l25: Int = { [unowned self] in self.l }()
783782

784783
nonisolated lazy var l31: Int = { v }()
785-
// expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}}
784+
// expected-error@-1 {{actor-isolated default value in a nonisolated context}}
786785
nonisolated lazy var l32: Int = v
787-
// expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}}
786+
// expected-error@-1 {{actor-isolated default value in a nonisolated context}}
788787
nonisolated lazy var l33: Int = { self.v }()
789-
// expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}}
788+
// expected-error@-1 {{actor-isolated default value in a nonisolated context}}
790789
nonisolated lazy var l34: Int = self.v
791-
// expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}}
790+
// expected-error@-1 {{actor-isolated default value in a nonisolated context}}
792791
nonisolated lazy var l35: Int = { [unowned self] in self.v }()
793-
// expected-error@-1 {{actor-isolated property 'v' can not be referenced from a non-isolated context}}
792+
// expected-error@-1 {{actor-isolated default value in a nonisolated context}}
794793

795794
nonisolated lazy var l41: Int = { l }()
796795
nonisolated lazy var l42: Int = l

test/Concurrency/global_actor_inference.swift

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// RUN: %empty-directory(%t)
22

33
// RUN: %target-swift-frontend -emit-module -emit-module-path %t/other_global_actor_inference.swiftmodule -module-name other_global_actor_inference -strict-concurrency=complete %S/Inputs/other_global_actor_inference.swift
4-
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify
5-
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted
4+
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -verify-additional-prefix minimal-targeted-
5+
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=targeted -verify-additional-prefix minimal-targeted-
66
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -verify-additional-prefix complete-tns-
77
// RUN: %target-swift-frontend -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -strict-concurrency=complete -enable-experimental-feature RegionBasedIsolation -verify-additional-prefix complete-tns-
88

@@ -437,13 +437,15 @@ actor WrapperActorBad2<Wrapped: Sendable> {
437437
struct WrapperWithMainActorDefaultInit {
438438
var wrappedValue: Int { fatalError() }
439439

440-
@MainActor init() {} // expected-note 2 {{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
440+
@MainActor init() {} // expected-note {{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
441+
// expected-minimal-targeted-note@-1 {{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
441442
}
442443

443444
actor ActorWithWrapper {
444445
@WrapperOnActor var synced: Int = 0
445446
// expected-note@-1 3{{property declared here}}
446-
@WrapperWithMainActorDefaultInit var property: Int // expected-error {{call to main actor-isolated initializer 'init()' in a synchronous actor-isolated context}}
447+
@WrapperWithMainActorDefaultInit var property: Int // expected-minimal-targeted-error {{call to main actor-isolated initializer 'init()' in a synchronous actor-isolated context}}
448+
// expected-complete-tns-error@-1 {{main actor-isolated default value in a actor-isolated context}}
447449
func f() {
448450
_ = synced // expected-error{{main actor-isolated property 'synced' can not be referenced on a different actor instance}}
449451
_ = $synced // expected-error{{global actor 'SomeGlobalActor'-isolated property '$synced' can not be referenced on a different actor instance}}
@@ -557,8 +559,9 @@ struct WrapperOnUnsafeActor<Wrapped> {
557559
}
558560
}
559561

562+
// HasWrapperOnUnsafeActor gets an inferred @MainActor attribute.
560563
struct HasWrapperOnUnsafeActor {
561-
@WrapperOnUnsafeActor var synced: Int = 0
564+
@WrapperOnUnsafeActor var synced: Int = 0 // expected-complete-tns-error {{global actor 'OtherGlobalActor'-isolated default value in a main actor-isolated context}}
562565
// expected-note @-1 3{{property declared here}}
563566
// expected-complete-tns-note @-2 3{{property declared here}}
564567

@@ -643,11 +646,11 @@ func acceptAsyncSendableClosureInheriting<T>(@_inheritActorContext _: @Sendable
643646

644647
// defer bodies inherit global actor-ness
645648
@MainActor
646-
var statefulThingy: Bool = false // expected-note {{var declared here}}
649+
var statefulThingy: Bool = false // expected-minimal-targeted-note {{var declared here}}
647650
// expected-complete-tns-error @-1 {{top-level code variables cannot have a global actor}}
648651

649652
@MainActor
650-
func useFooInADefer() -> String { // expected-note {{calls to global function 'useFooInADefer()' from outside of its actor context are implicitly asynchronous}}
653+
func useFooInADefer() -> String { // expected-minimal-targeted-note {{calls to global function 'useFooInADefer()' from outside of its actor context are implicitly asynchronous}}
651654
defer {
652655
statefulThingy = true
653656
}
@@ -677,9 +680,11 @@ class Cutter {
677680

678681
@SomeGlobalActor
679682
class Butter {
680-
var a = useFooInADefer() // expected-error {{call to main actor-isolated global function 'useFooInADefer()' in a synchronous global actor 'SomeGlobalActor'-isolated context}}
683+
var a = useFooInADefer() // expected-minimal-targeted-error {{call to main actor-isolated global function 'useFooInADefer()' in a synchronous global actor 'SomeGlobalActor'-isolated context}}
684+
// expected-complete-tns-error@-1 {{main actor-isolated default value in a global actor 'SomeGlobalActor'-isolated context}}
681685

682-
nonisolated let b = statefulThingy // expected-error {{main actor-isolated var 'statefulThingy' can not be referenced from a non-isolated context}}
686+
nonisolated let b = statefulThingy // expected-minimal-targeted-error {{main actor-isolated var 'statefulThingy' can not be referenced from a non-isolated context}}
687+
// expected-complete-tns-error@-1 {{main actor-isolated default value in a nonisolated context}}
683688

684689
var c: Int = {
685690
return getGlobal7()

test/Concurrency/predates_concurrency.swift

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,15 @@ func testElsewhere(x: X) {
7373
// expected-complete-tns-note @-1 {{calls to global function 'onMainActorAlways()' from outside of its actor context are implicitly asynchronous}}
7474

7575
@preconcurrency @MainActor class MyModelClass {
76-
// expected-complete-tns-note @-1 {{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
76+
77+
// default init() is 'nonisolated' in '-strict-concurrency=complete'
78+
7779
func f() { }
7880
// expected-complete-tns-note @-1 {{calls to instance method 'f()' from outside of its actor context are implicitly asynchronous}}
7981
}
8082

8183
func testCalls(x: X) {
82-
// expected-complete-tns-note @-1 3{{add '@MainActor' to make global function 'testCalls(x:)' part of global actor 'MainActor'}}
84+
// expected-complete-tns-note @-1 2{{add '@MainActor' to make global function 'testCalls(x:)' part of global actor 'MainActor'}}
8385
unsafelyMainActorClosure {
8486
onMainActor()
8587
}
@@ -102,8 +104,9 @@ func testCalls(x: X) {
102104
// Ok with minimal/targeted concurrency, Not ok with complete.
103105
let _: () -> Void = onMainActorAlways // expected-complete-tns-warning {{converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'}}
104106

105-
// both okay with minimal/targeted... an error with complete.
106-
let c = MyModelClass() // expected-complete-tns-warning {{call to main actor-isolated initializer 'init()' in a synchronous nonisolated context}}
107+
let c = MyModelClass()
108+
109+
// okay with minimal/targeted... an error with complete.
107110
c.f() // expected-complete-tns-warning {{call to main actor-isolated instance method 'f()' in a synchronous nonisolated context}}
108111
}
109112

@@ -113,8 +116,9 @@ func testCallsWithAsync() async {
113116

114117
let _: () -> Void = onMainActorAlways // expected-warning {{converting function value of type '@MainActor () -> ()' to '() -> Void' loses global actor 'MainActor'}}
115118

116-
let c = MyModelClass() // expected-warning{{expression is 'async' but is not marked with 'await'}}
117-
// expected-note@-1{{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
119+
let c = MyModelClass() // expected-minimal-targeted-warning{{expression is 'async' but is not marked with 'await'}}
120+
// expected-minimal-targeted-note@-1{{calls to initializer 'init()' from outside of its actor context are implicitly asynchronous}}
121+
118122
c.f() // expected-warning{{expression is 'async' but is not marked with 'await'}}
119123
// expected-note@-1{{calls to instance method 'f()' from outside of its actor context are implicitly asynchronous}}
120124
}

0 commit comments

Comments
 (0)