Skip to content

Commit 4681b9b

Browse files
committed
AST: Break circularity in qualified lookup into protocol or extension with 'Self' constraints
1 parent 5cd7404 commit 4681b9b

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
@@ -594,6 +594,14 @@ SelfBoundsFromWhereClauseRequest::evaluate(
594594
auto *extDecl = decl.dyn_cast<ExtensionDecl *>();
595595

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

@@ -623,7 +631,7 @@ SelfBoundsFromWhereClauseRequest::evaluate(
623631
// Resolve the right-hand side.
624632
DirectlyReferencedTypeDecls rhsDecls;
625633
if (auto typeRepr = req.getConstraintRepr()) {
626-
rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, dc);
634+
rhsDecls = directReferencesForTypeRepr(evaluator, ctx, typeRepr, lookupDC);
627635
} else if (Type type = req.getConstraint()) {
628636
rhsDecls = directReferencesForType(type);
629637
}
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)