Skip to content

Commit a5b15ed

Browse files
committed
[Concurrency] Substitute into superclass global actors when inheriting them.
1 parent 11cf3ce commit a5b15ed

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1178,8 +1178,19 @@ ActorIsolation ActorIsolationRequest::evaluate(
11781178
if (auto classDecl = dyn_cast<ClassDecl>(value)) {
11791179
if (auto superclassDecl = classDecl->getSuperclassDecl()) {
11801180
auto superclassIsolation = getActorIsolation(superclassDecl);
1181-
if (!superclassIsolation.isUnspecified())
1181+
if (!superclassIsolation.isUnspecified()) {
1182+
if (superclassIsolation.requiresSubstitution()) {
1183+
Type superclassType = classDecl->getSuperclass();
1184+
if (!superclassType)
1185+
return ActorIsolation::forUnspecified();
1186+
1187+
SubstitutionMap subs = superclassType->getMemberSubstitutionMap(
1188+
classDecl->getModuleContext(), classDecl);
1189+
superclassIsolation = superclassIsolation.subst(subs);
1190+
}
1191+
11821192
return inferredIsolation(superclassIsolation);
1193+
}
11831194
}
11841195
}
11851196

test/Concurrency/global_actor_inference.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,20 @@ actor class GenericSub<T> : GenericSuper<[T]> {
138138
// ----------------------------------------------------------------------
139139
struct Container<T> {
140140
@GenericGlobalActor<T> class Superclass { }
141+
@GenericGlobalActor<[T]> class Superclass2 { }
141142
}
142143

143144
struct OtherContainer<U> {
144145
// Okay to change the global actor in a subclass.
145146
@GenericGlobalActor<[U]> class Subclass1 : Container<[U]>.Superclass { }
146147
@GenericGlobalActor<U> class Subclass2 : Container<[U]>.Superclass { }
148+
149+
// Ensure that substitutions work properly when inheriting.
150+
class Subclass3<V> : Container<(U, V)>.Superclass2 {
151+
func method() { } // expected-note{{only asynchronous methods can be used outside the actor instance}}
152+
153+
@OtherGlobalActor func testMethod() {
154+
method() // expected-error{{instance method 'method()' isolated to global actor 'GenericGlobalActor<[(U, V)]>' can not be referenced from different global actor 'OtherGlobalActor'}}
155+
}
156+
}
147157
}

0 commit comments

Comments
 (0)