Skip to content

Commit bc90427

Browse files
authored
Merge pull request swiftlang#38575 from slavapestov/actor-isolation-cycle-5.5
Sema: Kick off ActorIsolationRequest after checking conformances to avoid cycles [5.5]
2 parents 6edfdda + b6e0bf3 commit bc90427

File tree

5 files changed

+38
-6
lines changed

5 files changed

+38
-6
lines changed

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,7 +1563,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
15631563
// Force some requests, which can produce diagnostics.
15641564

15651565
// Check redeclaration.
1566-
(void) evaluateOrDefault(decl->getASTContext().evaluator,
1566+
(void) evaluateOrDefault(Context.evaluator,
15671567
CheckRedeclarationRequest{VD}, {});
15681568

15691569
// Compute access level.
@@ -1577,8 +1577,11 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
15771577
(void) VD->isObjC();
15781578
(void) VD->isDynamic();
15791579

1580-
// Check for actor isolation.
1581-
(void)getActorIsolation(VD);
1580+
// Check for actor isolation of top-level and local declarations.
1581+
// Declarations inside types are handled in checkConformancesInContext()
1582+
// to avoid cycles involving associated type inference.
1583+
if (!VD->getDeclContext()->isTypeContext())
1584+
(void) getActorIsolation(VD);
15821585

15831586
// If this is a member of a nominal type, don't allow it to have a name of
15841587
// "Type" or "Protocol" since we reserve the X.Type and X.Protocol
@@ -1589,7 +1592,7 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
15891592
VD->getName().isSimpleName(Context.Id_Protocol)) &&
15901593
VD->getNameLoc().isValid() &&
15911594
Context.SourceMgr.extractText({VD->getNameLoc(), 1}) != "`") {
1592-
auto &DE = getASTContext().Diags;
1595+
auto &DE = Context.Diags;
15931596
DE.diagnose(VD->getNameLoc(), diag::reserved_member_name,
15941597
VD->getName(), VD->getBaseIdentifier().str());
15951598
DE.diagnose(VD->getNameLoc(), diag::backticks_to_escape)

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5846,6 +5846,13 @@ void TypeChecker::checkConformancesInContext(IterableDeclContext *idc) {
58465846
// Check all conformances.
58475847
groupChecker.checkAllConformances();
58485848

5849+
// Check actor isolation.
5850+
for (auto *member : idc->getMembers()) {
5851+
if (auto *valueDecl = dyn_cast<ValueDecl>(member)) {
5852+
(void)getActorIsolation(valueDecl);
5853+
}
5854+
}
5855+
58495856
if (Context.TypeCheckerOpts.DebugGenericSignatures &&
58505857
!conformances.empty()) {
58515858
// Now that they're filled out, print out information about the conformances
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
public protocol P {
4+
associatedtype T
5+
@MainActor func f(_: T)
6+
@MainActor func g(_: T)
7+
}
8+
public struct S : P {
9+
public func g(_: Int) {}
10+
public func f(_: T) {}
11+
}

test/ModuleInterface/actor_isolation.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ public class C7 { }
6868
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
6969
extension C7: UnsafeSendable { }
7070

71+
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
72+
public protocol P2 {
73+
@SomeGlobalActor func method()
74+
}
75+
76+
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
77+
// CHECK: class {{(Test.)?}}C8 : {{(Test.)?}}P2 {
78+
public class C8 : P2 {
79+
// CHECK: @{{(Test.)?}}SomeGlobalActor public func method()
80+
public func method() {}
81+
}
82+
7183
// FIXME: Work around a bug where module printing depends on the "synthesized"
7284
// bit in conformances which is not serialized and not present in the textual
7385
// form.

test/decl/protocol/req/recursion.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,12 @@ public struct S<A: P> where A.T == S<A> { // expected-error {{circular reference
4949
// expected-note@-3 {{while resolving type 'S<A>'}}
5050
func f(a: A.T) {
5151
g(a: id(t: a)) // `a` has error type which is diagnosed as circular reference
52-
// expected-error@-1{{conflicting arguments to generic parameter 'T' ('A.T' (associated type of protocol 'P') vs. 'S<A>')}}
5352
_ = A.T.self
5453
}
5554

5655
func g(a: S<A>) {
5756
f(a: id(t: a))
58-
// expected-error@-1 {{conflicting arguments to generic parameter 'T' ('S<A>' vs. 'A.T' (associated type of protocol 'P')}}
57+
// expected-error@-1 {{cannot convert value of type 'S<A>' to expected argument type 'A.T'}}
5958
_ = S<A>.self
6059
}
6160

0 commit comments

Comments
 (0)