Skip to content

Commit d922041

Browse files
authored
Merge pull request swiftlang#30740 from xedin/rdar-61084565
[ConstraintSystem] Don't include self-recursive dynamic member result…
2 parents 4f2d2dd + fdc535a commit d922041

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5821,6 +5821,15 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
58215821
}
58225822
}
58235823

5824+
// Exclude some of the dynamic member choices from results
5825+
// because using such choices would result in a self-recursive reference.
5826+
//
5827+
// This is required because if there are no viable/unviable choices
5828+
// `performMemberLookup` is going to attempt to lookup inaccessible
5829+
// members and results would include dynamic member subscripts which
5830+
// have already been excluded.
5831+
llvm::SmallPtrSet<ValueDecl *, 2> excludedDynamicMembers;
5832+
58245833
// Local function that adds the given declaration if it is a
58255834
// reasonable choice.
58265835
auto addChoice = [&](OverloadChoice candidate) {
@@ -5997,8 +6006,10 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
59976006
if (auto kpElt = memberLocator->getLastElementAs<KPDynamicMemberElt>()) {
59986007
auto *keyPath = kpElt->getKeyPathDecl();
59996008
if (isSelfRecursiveKeyPathDynamicMemberLookup(*this, baseTy,
6000-
memberLocator))
6009+
memberLocator)) {
6010+
excludedDynamicMembers.insert(candidate.getDecl());
60016011
return;
6012+
}
60026013

60036014
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
60046015
// If this is an attempt to access read-only member via
@@ -6234,6 +6245,9 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
62346245
return result;
62356246
}
62366247

6248+
if (excludedDynamicMembers.count(cand))
6249+
continue;
6250+
62376251
result.addUnviable(getOverloadChoice(cand, /*isBridged=*/false,
62386252
/*isUnwrappedOptional=*/false),
62396253
MemberLookupResult::UR_Inaccessible);

test/Constraints/subscript.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,16 @@ func test_generic_subscript_requirements_mismatch_diagnostics() {
203203

204204
s[number: ["hello"]] // expected-error {{subscript 'subscript(number:)' requires that 'String' conform to 'BinaryInteger'}}
205205
}
206+
207+
// rdar://61084565 - infinite recursion in dynamic member lookup
208+
func rdar61084565() {
209+
@dynamicMemberLookup
210+
struct Foo {
211+
subscript(dynamicMember _: KeyPath<Foo, Int>) -> Int {
212+
return 42
213+
}
214+
}
215+
216+
let a = Foo()
217+
a[] // expected-error {{value of type 'Foo' has no subscripts}}
218+
}

0 commit comments

Comments
 (0)