Skip to content

Commit 72559bd

Browse files
authored
Merge pull request #31140 from LucianoPAlmeida/SR-12425-crash-dynamic-member-key-path
[SR-12626] Fix crash when non WritableKeyPath to a set subscript assign
2 parents c59abcd + ab81236 commit 72559bd

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7802,6 +7802,13 @@ ConstraintSystem::simplifyKeyPathApplicationConstraint(
78027802
return SolutionKind::Unsolved;
78037803
};
78047804

7805+
// When locator points to a KeyPathDynamicMemberLookup, reject the
7806+
// key path application.
7807+
auto last = locator.last();
7808+
if (last && last->isKeyPathDynamicMember()) {
7809+
return SolutionKind::Error;
7810+
}
7811+
78057812
if (auto clas = keyPathTy->getAs<NominalType>()) {
78067813
if (clas->getDecl() == getASTContext().getAnyKeyPathDecl()) {
78077814
// Read-only keypath, whose projected value is upcast to `Any?`.

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,3 +789,31 @@ func test_combination_of_keypath_and_string_lookups() {
789789
_ = outer.hello.world // Ok
790790
}
791791
}
792+
793+
// SR-12626
794+
@dynamicMemberLookup
795+
struct SR12626 {
796+
var i: Int
797+
798+
subscript(dynamicMember member: KeyPath<SR12626, Int>) -> Int {
799+
get { self[keyPath: member] }
800+
set { self[keyPath: member] = newValue } // expected-error {{cannot assign through subscript: 'member' is a read-only key path}}
801+
}
802+
}
803+
804+
// SR-12245
805+
public struct SR12425_S {}
806+
807+
@dynamicMemberLookup
808+
public struct SR12425_R {}
809+
810+
internal var rightStructInstance: SR12425_R = SR12425_R()
811+
812+
public extension SR12425_R {
813+
subscript<T>(dynamicMember member: WritableKeyPath<SR12425_S, T>) -> T {
814+
// TODO(Diagnostics): bad diagnostic for member assign.
815+
// A better diagnostic would be: key path of type WritableKeyPath<SR12425_S, T> cannot be applied to a base of type SR12425_R
816+
get { rightStructInstance[keyPath: member] } // expected-error {{cannot convert return expression of type 'Any?' to return type 'T'}}
817+
set { rightStructInstance[keyPath: member] = newValue } // expected-error {{type of expression is ambiguous without more context}}
818+
}
819+
}

0 commit comments

Comments
 (0)