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 @@ -4586,30 +4586,43 @@ getIsolationFromConformances(NominalTypeDecl *nominal) {
45864586static std::optional<ActorIsolation>
45874587getIsolationFromInheritedProtocols (ProtocolDecl *protocol) {
45884588 std::optional<ActorIsolation> foundIsolation;
4589- for (auto inherited : protocol->getInheritedProtocols ()) {
4590- switch (auto protoIsolation = getActorIsolation (inherited)) {
4589+ bool conflict = false ;
4590+
4591+ auto inferIsolation = [&](ValueDecl *decl) {
4592+ switch (auto protoIsolation = getActorIsolation (decl)) {
45914593 case ActorIsolation::ActorInstance:
45924594 case ActorIsolation::Unspecified:
45934595 case ActorIsolation::Nonisolated:
45944596 case ActorIsolation::NonisolatedUnsafe:
4595- break ;
4597+ return ;
45964598
45974599 case ActorIsolation::Erased:
45984600 llvm_unreachable (" protocol cannot have erased isolation" );
45994601
46004602 case ActorIsolation::GlobalActor:
46014603 if (!foundIsolation) {
46024604 foundIsolation = protoIsolation;
4603- continue ;
4605+ return ;
46044606 }
46054607
46064608 if (*foundIsolation != protoIsolation)
4607- return std:: nullopt ;
4609+ conflict = true ;
46084610
4609- break ;
4611+ return ;
46104612 }
4613+ };
4614+
4615+ for (auto inherited : protocol->getInheritedProtocols ()) {
4616+ inferIsolation (inherited);
46114617 }
46124618
4619+ if (auto *superclass = protocol->getSuperclassDecl ()) {
4620+ inferIsolation (superclass);
4621+ }
4622+
4623+ if (conflict)
4624+ return std::nullopt ;
4625+
46134626 return foundIsolation;
46144627}
46154628
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