Skip to content

Commit a9da2a5

Browse files
committed
AST: Break circularity in qualified lookup into protocol or extension with 'Self' constraints
1 parent ed89656 commit a9da2a5

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

lib/AST/NameLookup.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,14 @@ SelfBoundsFromWhereClauseRequest::evaluate(
590590
auto *extDecl = decl.dyn_cast<ExtensionDecl *>();
591591

592592
DeclContext *dc = protoDecl ? (DeclContext *)protoDecl : (DeclContext *)extDecl;
593+
594+
// A protocol or extension 'where' clause can reference associated types of
595+
// the protocol itself, so we have to start unqualified lookup from 'dc'.
596+
//
597+
// However, the right hand side of a 'Self' conformance constraint must be
598+
// resolved before unqualified lookup into 'dc' can work, so we make an
599+
// exception here and begin lookup from the parent context instead.
600+
auto *lookupDC = dc->getParent();
593601
auto requirements = protoDecl ? protoDecl->getTrailingWhereClause()
594602
: extDecl->getTrailingWhereClause();
595603

@@ -619,7 +627,7 @@ SelfBoundsFromWhereClauseRequest::evaluate(
619627
// Resolve the right-hand side.
620628
DirectlyReferencedTypeDecls rhsDecls;
621629
if (auto typeRepr = req.getConstraintRepr()) {
622-
rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc);
630+
rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, lookupDC);
623631
} else if (Type type = req.getConstraint()) {
624632
rhsDecls = directReferencesForType(type);
625633
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-typecheck-verify-swift -debug-cycles 2>&1 | %FileCheck --allow-empty %s
2+
3+
// Verify that protocol where clause lookups don't cause cyclic dependencies.
4+
5+
// expected-no-diagnostics
6+
7+
class C { }
8+
protocol Q { }
9+
protocol P where Self : Q, Self : C { }
10+
11+
// CHECK-NOT: CYCLE DETECTED
12+

0 commit comments

Comments
 (0)