Skip to content

Commit 7d44f6a

Browse files
authored
Merge pull request #35270 from DougGregor/concurrency-override-actor-isolation-fixes
Concurrency override actor isolation fixes
2 parents e45dd64 + 5d43c87 commit 7d44f6a

File tree

3 files changed

+50
-9
lines changed

3 files changed

+50
-9
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,6 +1752,16 @@ static Optional<ActorIsolation> getIsolationFromWitnessedRequirements(
17521752
return std::get<1>(isolatedRequirements.front());
17531753
}
17541754

1755+
// Check whether a declaration is an asynchronous handler.
1756+
static bool isAsyncHandler(ValueDecl *value) {
1757+
if (auto func = dyn_cast<AbstractFunctionDecl>(value)) {
1758+
if (func->isAsyncHandler())
1759+
return true;
1760+
}
1761+
1762+
return false;
1763+
}
1764+
17551765
ActorIsolation ActorIsolationRequest::evaluate(
17561766
Evaluator &evaluator, ValueDecl *value) const {
17571767
// If this declaration has one of the actor isolation attributes, report
@@ -1807,12 +1817,15 @@ ActorIsolation ActorIsolationRequest::evaluate(
18071817
// If the declaration overrides another declaration, it must have the same
18081818
// actor isolation.
18091819
if (auto overriddenValue = value->getOverriddenDecl()) {
1810-
if (auto isolation = getActorIsolation(overriddenValue)) {
1820+
// Ignore the overridden declaration's isolation for an async handler,
1821+
// because async handlers dispatch to wherever they need to be.
1822+
if (!isAsyncHandler(value)) {
1823+
auto isolation = getActorIsolation(overriddenValue);
18111824
SubstitutionMap subs;
18121825
if (auto env = value->getInnermostDeclContext()
18131826
->getGenericEnvironmentOfContext()) {
18141827
subs = SubstitutionMap::getOverrideSubstitutions(
1815-
overriddenValue, value, subs);
1828+
overriddenValue, value, subs);
18161829
}
18171830

18181831
return inferredIsolation(isolation.subst(subs));
@@ -1888,6 +1901,10 @@ void swift::checkOverrideActorIsolation(ValueDecl *value) {
18881901
if (!overridden)
18891902
return;
18901903

1904+
// Actor isolation doesn't matter for async handlers.
1905+
if (isAsyncHandler(value))
1906+
return;
1907+
18911908
// Determine the actor isolation of this declaration.
18921909
auto isolation = getActorIsolation(value);
18931910

test/Concurrency/global_actor_inference.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,37 @@ struct OtherContainer<U> {
177177
}
178178
}
179179

180+
class SuperclassWithGlobalActors {
181+
@GenericGlobalActor<Int> func f() { }
182+
@GenericGlobalActor<Int> func g() { } // expected-note{{overridden declaration is here}}
183+
func h() { }
184+
func i() { }
185+
func j() { }
186+
}
187+
188+
@GenericGlobalActor<String>
189+
class SubclassWithGlobalActors : SuperclassWithGlobalActors {
190+
override func f() { } // okay: inferred to @GenericGlobalActor<Int>
191+
192+
@GenericGlobalActor<String> override func g() { } // expected-error{{global actor 'GenericGlobalActor<String>'-isolated instance method 'g()' has different actor isolation from global actor 'GenericGlobalActor<Int>'-isolated overridden declaration}}
193+
194+
override func h() { } // okay: inferred to unspecified
195+
196+
func onGenericGlobalActorString() { }
197+
@GenericGlobalActor<Int> func onGenericGlobalActorInt() { }
198+
199+
@asyncHandler @GenericGlobalActor<String>
200+
override func i() { // okay to differ from superclass because it's an asyncHandler.
201+
onGenericGlobalActorString()
202+
}
203+
204+
@asyncHandler
205+
override func j() { // okay, isolated to GenericGlobalActor<String>
206+
onGenericGlobalActorString() // okay
207+
onGenericGlobalActorInt() // expected-error{{call is 'async' but is not marked with 'await'}}
208+
}
209+
}
210+
180211
// ----------------------------------------------------------------------
181212
// Global actor inference for unspecified contexts
182213
// ----------------------------------------------------------------------

test/Incremental/Verifier/single-file-private/AnyObject.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,9 @@ func lookupOnAnyObject(object: AnyObject) { // expected-provides {{lookupOnAnyOb
7373
// expected-member {{Swift.CustomStringConvertible.someMethod}}
7474
// expected-member {{Swift.CustomDebugStringConvertible.someMethod}}
7575
// expected-member {{Swift.Equatable.someMember}}
76-
// expected-member{{Swift.CustomDebugStringConvertible.init}}
7776
// expected-member{{Swift.CVarArg.someMember}}
7877
// expected-member{{Foundation._KeyValueCodingAndObservingPublishing.someMember}}
79-
// expected-member{{Swift.Equatable.init}}
80-
// expected-member{{Swift.Hashable.init}}
81-
// expected-member{{Swift.CVarArg.init}}
8278
// expected-member{{Foundation._KeyValueCodingAndObserving.someMember}}
83-
// expected-member{{Foundation._KeyValueCodingAndObservingPublishing.init}}
8479
// expected-member{{Swift.CustomDebugStringConvertible.someMember}}
8580
// expected-member{{Swift.CustomStringConvertible.someMember}}
86-
// expected-member{{Swift.CustomStringConvertible.init}}
8781
// expected-member{{Swift.Hashable.someMember}}
88-
// expected-member{{Foundation._KeyValueCodingAndObserving.init}}

0 commit comments

Comments
 (0)