Skip to content

Commit ac10f1e

Browse files
Merge pull request #78605 from AnthonyLatsis/gyromitra-esculenta-6.1
[6.1] ConformanceChecker: Make `actor_isolated_witness` call out the protocol
2 parents 1b3215f + fd65023 commit ac10f1e

12 files changed

+61
-51
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ NOTE(opaque_return_type_declared_here,none,
4242
"opaque return type declared here", ())
4343
NOTE(default_value_declared_here,none,
4444
"default value declared here", ())
45+
NOTE(protocol_requirement_declared_here,none,
46+
"requirement %0 declared here", (const ValueDecl *))
4547

4648
//------------------------------------------------------------------------------
4749
// MARK: Constraint solver diagnostics
@@ -5646,9 +5648,10 @@ NOTE(shared_state_make_immutable,none,
56465648
NOTE(shared_state_nonisolated_unsafe,none,
56475649
"disable concurrency-safety checks if accesses are protected by an external synchronization mechanism", (const ValueDecl *))
56485650
ERROR(actor_isolated_witness,none,
5649-
"%select{|distributed }0%1 %kind2 cannot be used to satisfy %3 protocol "
5650-
"requirement",
5651-
(bool, ActorIsolation, const ValueDecl *, ActorIsolation))
5651+
"%select{|distributed }0%1 %kind2 cannot be used to satisfy %3 "
5652+
"requirement from protocol %base4",
5653+
(bool, ActorIsolation, const ValueDecl *, ActorIsolation,
5654+
const ValueDecl *))
56525655
ERROR(actor_cannot_conform_to_global_actor_protocol,none,
56535656
"actor %0 cannot conform to global actor isolated protocol %1",
56545657
(Type, Type))

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3396,10 +3396,12 @@ ConformanceChecker::checkActorIsolation(ValueDecl *requirement,
33963396

33973397
// Complain that this witness cannot conform to the requirement due to
33983398
// actor isolation.
3399-
witness->diagnose(diag::actor_isolated_witness,
3400-
isDistributed && !isDistributedDecl(witness),
3401-
refResult.isolation, witness, requirementIsolation)
3402-
.limitBehaviorUntilSwiftVersion(behavior, 6);
3399+
witness
3400+
->diagnose(diag::actor_isolated_witness,
3401+
isDistributed && !isDistributedDecl(witness),
3402+
refResult.isolation, witness, requirementIsolation,
3403+
Conformance->getProtocol())
3404+
.limitBehaviorUntilSwiftVersion(behavior, 6);
34033405

34043406
// If we need 'distributed' on the witness, add it.
34053407
if (missingOptions.contains(MissingFlags::WitnessDistributed)) {
@@ -3437,8 +3439,12 @@ ConformanceChecker::checkActorIsolation(ValueDecl *requirement,
34373439
// If there are remaining options, they are missing async/throws on the
34383440
// requirement itself. If we have a source location for the requirement,
34393441
// provide those in a note.
3440-
if (missingOptions && requirement->getLoc().isValid() &&
3441-
isa<AbstractFunctionDecl>(requirement)) {
3442+
3443+
if (requirement->getLoc().isInvalid()) {
3444+
return std::nullopt;
3445+
}
3446+
3447+
if (missingOptions && isa<AbstractFunctionDecl>(requirement)) {
34423448
int suggestAddingModifiers = 0;
34433449
std::string modifiers;
34443450
if (missingOptions.contains(MissingFlags::RequirementAsync)) {
@@ -3484,7 +3490,8 @@ ConformanceChecker::checkActorIsolation(ValueDecl *requirement,
34843490
diag.fixItInsert(insertLoc, modifiers);
34853491
}
34863492
} else {
3487-
requirement->diagnose(diag::decl_declared_here, requirement);
3493+
requirement->diagnose(diag::protocol_requirement_declared_here,
3494+
requirement);
34883495
}
34893496

34903497
return std::nullopt;

test/Concurrency/actor_isolation.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ protocol SGA_Proto {
15101510
// try to override a MA method with inferred isolation from a protocol requirement
15111511
class SGA_MA: MA, SGA_Proto {
15121512
// expected-error@+2 {{call to global actor 'SomeGlobalActor'-isolated global function 'onions_sga()' in a synchronous main actor-isolated context}}
1513-
// expected-warning@+1 {{main actor-isolated instance method 'method()' cannot be used to satisfy global actor 'SomeGlobalActor'-isolated protocol requirement}}
1513+
// expected-warning@+1 {{main actor-isolated instance method 'method()' cannot be used to satisfy global actor 'SomeGlobalActor'-isolated requirement from protocol 'SGA_Proto'}}
15141514
override func method() { onions_sga() }
15151515
// expected-note@-1{{add 'nonisolated' to 'method()' to make this instance method not isolated to the actor}}{{3-3=nonisolated }}
15161516
}
@@ -1614,13 +1614,13 @@ class OverridesNonsiolatedInit: SuperWithNonisolatedInit {
16141614
class NonSendable {}
16151615

16161616
protocol NonisolatedProtocol {
1617-
var ns: NonSendable { get } // expected-note {{'ns' declared here}}
1617+
var ns: NonSendable { get } // expected-note {{requirement 'ns' declared here}}
16181618
}
16191619

16201620
actor ActorWithNonSendableLet: NonisolatedProtocol {
16211621
// expected-note@-1{{add '@preconcurrency' to the 'NonisolatedProtocol' conformance to defer isolation checking to run time}}{{32-32=@preconcurrency }}
16221622

1623-
// expected-warning@+1 {{actor-isolated property 'ns' cannot be used to satisfy nonisolated protocol requirement; this is an error in the Swift 6 language mode}}
1623+
// expected-warning@+1 {{actor-isolated property 'ns' cannot be used to satisfy nonisolated requirement from protocol 'NonisolatedProtocol'; this is an error in the Swift 6 language mode}}
16241624
let ns = NonSendable()
16251625
}
16261626

test/Concurrency/actor_isolation_unsafe.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ struct S3_P1: P1 {
4040

4141
struct S4_P1_not_quietly: P1 {
4242
@SomeGlobalActor func onMainActor() { }
43-
// expected-warning @-1 {{global actor 'SomeGlobalActor'-isolated instance method 'onMainActor()' cannot be used to satisfy main actor-isolated protocol requirement}}
43+
// expected-warning @-1 {{global actor 'SomeGlobalActor'-isolated instance method 'onMainActor()' cannot be used to satisfy main actor-isolated requirement from protocol 'P1'}}
4444
}
4545

4646
@SomeGlobalActor
4747
struct S4_P1: P1 {
48-
@SomeGlobalActor func onMainActor() { } // expected-warning{{global actor 'SomeGlobalActor'-isolated instance method 'onMainActor()' cannot be used to satisfy main actor-isolated protocol requirement}}
48+
@SomeGlobalActor func onMainActor() { } // expected-warning{{global actor 'SomeGlobalActor'-isolated instance method 'onMainActor()' cannot be used to satisfy main actor-isolated requirement from protocol 'P1'}}
4949
}
5050

5151
// expected-warning@+1 {{'(unsafe)' global actors are deprecated; use '@preconcurrency' instead}}

test/Concurrency/global_actor_inference.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,14 @@ func testNotAllInP1(nap1: NotAllInP1) { // expected-note{{add '@SomeGlobalActor'
120120
// Make sure we don't infer 'nonisolated' for stored properties.
121121
@MainActor
122122
protocol Interface {
123-
nonisolated var baz: Int { get } // expected-note{{'baz' declared here}}
123+
nonisolated var baz: Int { get } // expected-note{{requirement 'baz' declared here}}
124124
}
125125

126126
@MainActor
127127
class Object: Interface {
128128
// expected-note@-1{{add '@preconcurrency' to the 'Interface' conformance to defer isolation checking to run time}}{{15-15=@preconcurrency }}
129129

130-
var baz: Int = 42 // expected-warning{{main actor-isolated property 'baz' cannot be used to satisfy nonisolated protocol requirement}}
130+
var baz: Int = 42 // expected-warning{{main actor-isolated property 'baz' cannot be used to satisfy nonisolated requirement from protocol 'Interface'}}
131131
}
132132

133133

test/Concurrency/global_actor_inference_swift6.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ struct S3: InferenceConflict {
176176

177177
extension S3 {
178178
func f() { }
179-
// expected-error@-1{{global actor 'SomeGlobalActor'-isolated instance method 'f()' cannot be used to satisfy main actor-isolated protocol requirement}}
179+
// expected-error@-1{{global actor 'SomeGlobalActor'-isolated instance method 'f()' cannot be used to satisfy main actor-isolated requirement from protocol 'InferMainActorInherited'}}
180180
//expected-note@-2{{add 'nonisolated' to 'f()' to make this instance method not isolated to the actor}}
181181
}
182182

@@ -208,7 +208,7 @@ class C2: MainActorSuperclass, InferenceConflictWithSuperclass {
208208
func f() {}
209209

210210
func g() {}
211-
// expected-error@-1 {{main actor-isolated instance method 'g()' cannot be used to satisfy nonisolated protocol requirement}}
211+
// expected-error@-1 {{main actor-isolated instance method 'g()' cannot be used to satisfy nonisolated requirement from protocol 'InferenceConflictWithSuperclass'}}
212212
// expected-note@-2 {{add 'nonisolated' to 'g()' to make this instance method not isolated to the actor}}
213213
}
214214

test/Concurrency/preconcurrency_conformances.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ final class K : @preconcurrency Initializable {
107107
@MainActor
108108
final class MainActorK: Initializable {
109109
// expected-note@-1{{add '@preconcurrency' to the 'Initializable' conformance to defer isolation checking to run time}}{{25-25=@preconcurrency }}
110-
init() { } // expected-warning{{main actor-isolated initializer 'init()' cannot be used to satisfy nonisolated protocol requirement}}
110+
init() { } // expected-warning{{main actor-isolated initializer 'init()' cannot be used to satisfy nonisolated requirement from protocol 'Initializable'}}
111111
// expected-note@-1{{add 'nonisolated' to 'init()' to make this initializer not isolated to the actor}}
112112
}
113113

@@ -130,7 +130,7 @@ struct GlobalActor {
130130
protocol WithIndividuallyIsolatedRequirements {
131131
@MainActor var a: Int { get set }
132132
@GlobalActor var b: Int { get set }
133-
// expected-note@-1 {{'b' declared here}}
133+
// expected-note@-1 {{requirement 'b' declared here}}
134134

135135
@GlobalActor func test()
136136
// expected-note@-1 {{mark the protocol requirement 'test()' 'async' to allow actor-isolated conformances}}
@@ -144,21 +144,21 @@ do {
144144
var a: Int = 42
145145

146146
@MainActor var b: Int {
147-
// expected-warning@-1 {{main actor-isolated property 'b' cannot be used to satisfy global actor 'GlobalActor'-isolated protocol requirement}}
147+
// expected-warning@-1 {{main actor-isolated property 'b' cannot be used to satisfy global actor 'GlobalActor'-isolated requirement from protocol 'WithIndividuallyIsolatedRequirements'}}
148148
get { 0 }
149149
set {}
150150
}
151151

152152
@MainActor func test() {
153-
// expected-warning@-1 {{main actor-isolated instance method 'test()' cannot be used to satisfy global actor 'GlobalActor'-isolated protocol requirement}}
153+
// expected-warning@-1 {{main actor-isolated instance method 'test()' cannot be used to satisfy global actor 'GlobalActor'-isolated requirement from protocol 'WithIndividuallyIsolatedRequirements'}}
154154
}
155155
}
156156
}
157157

158158
@MainActor
159159
protocol WithNonIsolated {
160160
var prop: Int { get set }
161-
// expected-note@-1 {{'prop' declared here}}
161+
// expected-note@-1 {{requirement 'prop' declared here}}
162162
nonisolated func test()
163163
// expected-note@-1 {{mark the protocol requirement 'test()' 'async' to allow actor-isolated conformances}}
164164
}
@@ -168,10 +168,10 @@ do {
168168
// expected-warning@-1 {{@preconcurrency attribute on conformance to 'WithNonIsolated' has no effect}}{{38-54=}}
169169

170170
@GlobalActor var prop: Int = 42
171-
// expected-warning@-1 {{global actor 'GlobalActor'-isolated property 'prop' cannot be used to satisfy main actor-isolated protocol requirement}}
171+
// expected-warning@-1 {{global actor 'GlobalActor'-isolated property 'prop' cannot be used to satisfy main actor-isolated requirement from protocol 'WithNonIsolated'}}
172172

173173
@MainActor func test() {}
174-
// expected-warning@-1 {{main actor-isolated instance method 'test()' cannot be used to satisfy nonisolated protocol requirement}}
174+
// expected-warning@-1 {{main actor-isolated instance method 'test()' cannot be used to satisfy nonisolated requirement from protocol 'WithNonIsolated'}}
175175
}
176176
}
177177

test/Concurrency/predates_concurrency.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ extension MainActorPreconcurrency: NotIsolated {
235235
// expected-complete-tns-note@-2{{add '@preconcurrency' to the 'NotIsolated' conformance to defer isolation checking to run time}}{{36-36=@preconcurrency }}
236236

237237
func requirement() {}
238-
// expected-complete-tns-warning@-1 {{main actor-isolated instance method 'requirement()' cannot be used to satisfy nonisolated protocol requirement}}
238+
// expected-complete-tns-warning@-1 {{main actor-isolated instance method 'requirement()' cannot be used to satisfy nonisolated requirement from protocol 'NotIsolated'}}
239239
// expected-complete-tns-note@-2 {{add 'nonisolated' to 'requirement()' to make this instance method not isolated to the actor}}
240240
// expected-complete-tns-note@-3 {{calls to instance method 'requirement()' from outside of its actor context are implicitly asynchronous}}
241241

test/Distributed/distributed_protocol_isolation.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,22 +109,22 @@ distributed actor Nope1_StrictlyLocal: StrictlyLocal {
109109
// expected-note@-1{{add '@preconcurrency' to the 'StrictlyLocal' conformance to defer isolation checking to run time}}
110110

111111
func local() {}
112-
// expected-error@-1{{distributed actor-isolated instance method 'local()' cannot be used to satisfy nonisolated protocol requirement}}
112+
// expected-error@-1{{distributed actor-isolated instance method 'local()' cannot be used to satisfy nonisolated requirement from protocol 'StrictlyLocal'}}
113113
// expected-note@-2{{add 'nonisolated' to 'local()' to make this instance method not isolated to the actor}}
114114
func localThrows() throws {}
115-
// expected-error@-1{{distributed actor-isolated instance method 'localThrows()' cannot be used to satisfy nonisolated protocol requirement}}
115+
// expected-error@-1{{distributed actor-isolated instance method 'localThrows()' cannot be used to satisfy nonisolated requirement from protocol 'StrictlyLocal'}}
116116
// expected-note@-2{{add 'nonisolated' to 'localThrows()' to make this instance method not isolated to the actor}}
117117
func localAsync() async {}
118-
// expected-error@-1{{distributed actor-isolated instance method 'localAsync()' cannot be used to satisfy nonisolated protocol requirement}}
118+
// expected-error@-1{{distributed actor-isolated instance method 'localAsync()' cannot be used to satisfy nonisolated requirement from protocol 'StrictlyLocal'}}
119119
// expected-note@-2{{add 'nonisolated' to 'localAsync()' to make this instance method not isolated to the actor}}
120120
}
121121
distributed actor Nope2_StrictlyLocal: StrictlyLocal {
122122
distributed func local() {}
123-
// expected-error@-1{{actor-isolated distributed instance method 'local()' cannot be used to satisfy nonisolated protocol requirement}}
123+
// expected-error@-1{{actor-isolated distributed instance method 'local()' cannot be used to satisfy nonisolated requirement from protocol 'StrictlyLocal'}}
124124
distributed func localThrows() throws {}
125-
// expected-error@-1{{actor-isolated distributed instance method 'localThrows()' cannot be used to satisfy nonisolated protocol requirement}}
125+
// expected-error@-1{{actor-isolated distributed instance method 'localThrows()' cannot be used to satisfy nonisolated requirement from protocol 'StrictlyLocal'}}
126126
distributed func localAsync() async {}
127-
// expected-error@-1{{actor-isolated distributed instance method 'localAsync()' cannot be used to satisfy nonisolated protocol requirement}}
127+
// expected-error@-1{{actor-isolated distributed instance method 'localAsync()' cannot be used to satisfy nonisolated requirement from protocol 'StrictlyLocal'}}
128128
}
129129
distributed actor OK_StrictlyLocal: StrictlyLocal {
130130
nonisolated func local() {}
@@ -162,7 +162,7 @@ distributed actor Nope1_AsyncThrowsAll: AsyncThrowsAll {
162162
// expected-note@-1{{add '@preconcurrency' to the 'AsyncThrowsAll' conformance to defer isolation checking to run time}}
163163

164164
func maybe(param: String, int: Int) async throws -> Int { 111 }
165-
// expected-error@-1{{distributed actor-isolated instance method 'maybe(param:int:)' cannot be used to satisfy nonisolated protocol requirement}}
165+
// expected-error@-1{{distributed actor-isolated instance method 'maybe(param:int:)' cannot be used to satisfy nonisolated requirement from protocol 'AsyncThrowsAll'}}
166166
// expected-note@-2{{add 'nonisolated' to 'maybe(param:int:)' to make this instance method not isolated to the actor}}
167167
// expected-note@-3{{add 'distributed' to 'maybe(param:int:)' to make this instance method satisfy the protocol requirement}}
168168
}
@@ -209,7 +209,7 @@ distributed actor DA_TerminationWatchingA: TerminationWatchingA {
209209
// expected-note@-1{{add '@preconcurrency' to the 'TerminationWatchingA' conformance to defer isolation checking to run time}}
210210

211211
func terminated(a: String) { }
212-
// expected-error@-1{{distributed actor-isolated instance method 'terminated(a:)' cannot be used to satisfy nonisolated protocol requirement}}
212+
// expected-error@-1{{distributed actor-isolated instance method 'terminated(a:)' cannot be used to satisfy nonisolated requirement from protocol 'TerminationWatchingA'}}
213213
// expected-note@-2{{add 'nonisolated' to 'terminated(a:)' to make this instance method not isolated to the actor}}
214214
}
215215

test/decl/class/actor/conformance.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ extension MyActor: AsyncProtocol {
1515
}
1616

1717
protocol SyncProtocol {
18-
var propertyA: Int { get } // expected-note{{'propertyA' declared here}}
19-
var propertyB: Int { get set } // expected-note{{'propertyB' declared here}}
18+
var propertyA: Int { get } // expected-note{{requirement 'propertyA' declared here}}
19+
var propertyB: Int { get set } // expected-note{{requirement 'propertyB' declared here}}
2020

2121
func syncMethodA() // expected-note{{mark the protocol requirement 'syncMethodA()' 'async' to allow actor-isolated conformances}}{{21-21= async}}
2222

@@ -28,7 +28,7 @@ protocol SyncProtocol {
2828

2929
func syncMethodG() throws -> Void // expected-note{{mark the protocol requirement 'syncMethodG()' 'async' to allow actor-isolated conformances}}{{22-22=async }}
3030

31-
subscript (index: Int) -> String { get } // expected-note{{'subscript(_:)' declared here}}
31+
subscript (index: Int) -> String { get } // expected-note{{requirement 'subscript(_:)' declared here}}
3232

3333
static func staticMethod()
3434
static var staticProperty: Int { get }
@@ -39,33 +39,33 @@ actor OtherActor: SyncProtocol {
3939
// expected-note@-1{{add '@preconcurrency' to the 'SyncProtocol' conformance to defer isolation checking to run time}}{{19-19=@preconcurrency }}
4040

4141
var propertyB: Int = 17
42-
// expected-error@-1{{actor-isolated property 'propertyB' cannot be used to satisfy nonisolated protocol requirement}}
42+
// expected-error@-1{{actor-isolated property 'propertyB' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
4343

4444
var propertyA: Int { 17 }
45-
// expected-error@-1{{actor-isolated property 'propertyA' cannot be used to satisfy nonisolated protocol requirement}}
45+
// expected-error@-1{{actor-isolated property 'propertyA' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
4646

4747
func syncMethodA() { }
48-
// expected-error@-1{{actor-isolated instance method 'syncMethodA()' cannot be used to satisfy nonisolated protocol requirement}}
48+
// expected-error@-1{{actor-isolated instance method 'syncMethodA()' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
4949
// expected-note@-2{{add 'nonisolated' to 'syncMethodA()' to make this instance method not isolated to the actor}}{{3-3=nonisolated }}
5050

5151
// nonisolated methods are okay.
5252
// FIXME: Consider suggesting nonisolated if this didn't match.
5353
nonisolated func syncMethodC() -> Int { 5 }
5454

5555
func syncMethodE() -> Void { }
56-
// expected-error@-1{{actor-isolated instance method 'syncMethodE()' cannot be used to satisfy nonisolated protocol requirement}}
56+
// expected-error@-1{{actor-isolated instance method 'syncMethodE()' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
5757
// expected-note@-2{{add 'nonisolated' to 'syncMethodE()' to make this instance method not isolated to the actor}}{{3-3=nonisolated }}
5858

5959
func syncMethodF(param: String) -> Int { 5 }
60-
// expected-error@-1{{actor-isolated instance method 'syncMethodF(param:)' cannot be used to satisfy nonisolated protocol requirement}}
60+
// expected-error@-1{{actor-isolated instance method 'syncMethodF(param:)' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
6161
// expected-note@-2{{add 'nonisolated' to 'syncMethodF(param:)' to make this instance method not isolated to the actor}}{{3-3=nonisolated }}
6262

6363
func syncMethodG() { }
64-
// expected-error@-1{{actor-isolated instance method 'syncMethodG()' cannot be used to satisfy nonisolated protocol requirement}}
64+
// expected-error@-1{{actor-isolated instance method 'syncMethodG()' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
6565
// expected-note@-2{{add 'nonisolated' to 'syncMethodG()' to make this instance method not isolated to the actor}}{{3-3=nonisolated }}
6666

6767
subscript (index: Int) -> String { "\(index)" }
68-
// expected-error@-1{{actor-isolated subscript 'subscript(_:)' cannot be used to satisfy nonisolated protocol requirement}}
68+
// expected-error@-1{{actor-isolated subscript 'subscript(_:)' cannot be used to satisfy nonisolated requirement from protocol 'SyncProtocol'}}
6969
// expected-note@-2{{add 'nonisolated' to 'subscript(_:)' to make this subscript not isolated to the actor}}{{3-3=nonisolated }}
7070

7171
// Static methods and properties are okay.

0 commit comments

Comments
 (0)