File tree Expand file tree Collapse file tree 2 files changed +54
-7
lines changed Expand file tree Collapse file tree 2 files changed +54
-7
lines changed Original file line number Diff line number Diff line change @@ -4603,30 +4603,43 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
46034603static std::optional<ActorIsolation>
46044604getIsolationFromInheritedProtocols (ProtocolDecl *protocol) {
46054605 std::optional<ActorIsolation> foundIsolation;
4606- for (auto inherited : protocol->getInheritedProtocols ()) {
4607- switch (auto protoIsolation = getActorIsolation (inherited)) {
4606+ bool conflict = false ;
4607+
4608+ auto inferIsolation = [&](ValueDecl *decl) {
4609+ switch (auto protoIsolation = getActorIsolation (decl)) {
46084610 case ActorIsolation::ActorInstance:
46094611 case ActorIsolation::Unspecified:
46104612 case ActorIsolation::Nonisolated:
46114613 case ActorIsolation::NonisolatedUnsafe:
4612- break ;
4614+ return ;
46134615
46144616 case ActorIsolation::Erased:
46154617 llvm_unreachable (" protocol cannot have erased isolation" );
46164618
46174619 case ActorIsolation::GlobalActor:
46184620 if (!foundIsolation) {
46194621 foundIsolation = protoIsolation;
4620- continue ;
4622+ return ;
46214623 }
46224624
46234625 if (*foundIsolation != protoIsolation)
4624- return std:: nullopt ;
4626+ conflict = true ;
46254627
4626- break ;
4628+ return ;
46274629 }
4630+ };
4631+
4632+ for (auto inherited : protocol->getInheritedProtocols ()) {
4633+ inferIsolation (inherited);
46284634 }
46294635
4636+ if (auto *superclass = protocol->getSuperclassDecl ()) {
4637+ inferIsolation (superclass);
4638+ }
4639+
4640+ if (conflict)
4641+ return std::nullopt ;
4642+
46304643 return foundIsolation;
46314644}
46324645
Original file line number Diff line number Diff line change 22
33// RUN: %target-swift-frontend -swift-version 6 -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
44
5- // RUN: %target-swift-frontend -swift-version 6 -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify -enable-upcoming-feature GlobalActorIsolatedTypesUsability
5+ // RUN: %target-swift-frontend -swift-version 6 -I %t -disable-availability-checking %s -emit-sil -o /dev/null -verify
66
77// REQUIRES: concurrency
88
@@ -179,3 +179,37 @@ extension S3 {
179179 // expected-error@-1{{global actor 'SomeGlobalActor'-isolated instance method 'f()' cannot be used to satisfy main actor-isolated protocol requirement}}
180180 //expected-note@-2{{add 'nonisolated' to 'f()' to make this instance method not isolated to the actor}}
181181}
182+
183+ @MainActor
184+ func onMain( ) { }
185+
186+ @MainActor
187+ class MainActorSuperclass { }
188+
189+ protocol InferMainFromSuperclass : MainActorSuperclass {
190+ func f( )
191+ }
192+
193+ class C1 : MainActorSuperclass , InferMainFromSuperclass {
194+ func f( ) {
195+ onMain ( ) // okay
196+ }
197+ }
198+
199+ protocol InferenceConflictWithSuperclass : MainActorSuperclass , InferSomeGlobalActor {
200+ func g( )
201+ // expected-note@-1 {{mark the protocol requirement 'g()' 'async' to allow actor-isolated conformances}}
202+ }
203+
204+
205+ class C2 : MainActorSuperclass , InferenceConflictWithSuperclass {
206+ //expected-note@-1 {{add '@preconcurrency' to the 'InferenceConflictWithSuperclass' conformance to defer isolation checking to run time}}
207+
208+ func f( ) { }
209+
210+ func g( ) { }
211+ // expected-error@-1 {{main actor-isolated instance method 'g()' cannot be used to satisfy nonisolated protocol requirement}}
212+ // expected-note@-2 {{add 'nonisolated' to 'g()' to make this instance method not isolated to the actor}}
213+ }
214+
215+
You can’t perform that action at this time.
0 commit comments