Skip to content

Commit 95be170

Browse files
committed
[CSApply] Support dynamic member lookup as component of key path dynamic member lookup
Previously solution application only supported references to key path dynamic member lookup as components but it should support both kinds. Resolves: rdar://problem/60225883 Resolves: [SR-12313](https://bugs.swift.org/browse/SR-12313)
1 parent f14e9a8 commit 95be170

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,8 +1966,9 @@ namespace {
19661966

19671967
// Looks like there is a chain of implicit `subscript(dynamicMember:)`
19681968
// calls necessary to resolve a member reference.
1969-
if (overload.choice.getKind() ==
1970-
OverloadChoiceKind::KeyPathDynamicMemberLookup) {
1969+
switch (overload.choice.getKind()) {
1970+
case OverloadChoiceKind::DynamicMemberLookup:
1971+
case OverloadChoiceKind::KeyPathDynamicMemberLookup: {
19711972
buildKeyPathSubscriptComponent(overload, dotLoc, /*indexExpr=*/nullptr,
19721973
ctx.Id_dynamicMember, componentLoc,
19731974
components);
@@ -1976,6 +1977,10 @@ namespace {
19761977
return keyPath;
19771978
}
19781979

1980+
default:
1981+
break;
1982+
}
1983+
19791984
// We can't reuse existing expression because type-check
19801985
// based diagnostics could hold the reference to original AST.
19811986
Expr *componentExpr = nullptr;

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,3 +764,28 @@ func test_infinite_self_recursion() {
764764
_ = Recurse<Int>().foo
765765
// expected-error@-1 {{value of type 'Recurse<Int>' has no dynamic member 'foo' using key path from root type 'Recurse<Int>'}}
766766
}
767+
768+
// rdar://problem/60225883 - crash during solution application (ExprRewritter::buildKeyPathDynamicMemberIndexExpr)
769+
func test_combination_of_keypath_and_string_lookups() {
770+
@dynamicMemberLookup
771+
struct Outer {
772+
subscript(dynamicMember member: String) -> Outer {
773+
Outer()
774+
}
775+
776+
subscript(dynamicMember member: KeyPath<Inner, Inner>) -> Outer {
777+
Outer()
778+
}
779+
}
780+
781+
@dynamicMemberLookup
782+
struct Inner {
783+
subscript(dynamicMember member: String) -> Inner {
784+
Inner()
785+
}
786+
}
787+
788+
func test(outer: Outer) {
789+
_ = outer.hello.world // Ok
790+
}
791+
}

0 commit comments

Comments
 (0)