[ConstraintSystem] Look through l-value while checking whether dynamic key path is recursive

Fix a crash in dynamic member lookup attempting to recursively
lookup a member on the same base type.

The problem is related to `isSelfRecursiveKeyPathDynamicMemberLookup`
which failed to look through l-value wrapping base type on each side of
the comparison, that's important because it's possible to have l-value
mismatch due to the fact that implicit call always gets l-value base
type but actual subscript which triggered dynamic lookup might be r-value.

Resolves: [SR-11743](https://bugs.swift.org/browse/SR-11743)
Resolves: rdar://problem/57091169
This commit is contained in:
Pavel Yaskevich
2020-02-24 19:38:20 -08:00
parent 853c0f545b
commit 2cdd78501c
2 changed files with 26 additions and 1 deletions

View File

@@ -483,3 +483,16 @@ func testDynamicMemberWithDefault(_ x: SR_11933) {
// CHECK: [[OUTER_KP:%[0-9]+]] = keypath $KeyPath<SR_11933, Int>, (root $SR_11933; gettable_property $Int, id @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath<HasDefaultedSubscript, Int>, SR_11933) -> Int, getter @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_11933, UnsafeRawPointer) -> @out Int, indices [%$0 : $KeyPath<HasDefaultedSubscript, Int> : $KeyPath<HasDefaultedSubscript, Int>], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP]])
_ = \SR_11933.[]
}
@dynamicMemberLookup
protocol SR_11743 {
subscript(dynamicMember member: KeyPath<Self, Any>) -> Any { get }
}
extension SR_11743 {
subscript(dynamicMember member: KeyPath<Self, Any>) -> Any {
self[keyPath: member] // Ok
// CHECK: function_ref @swift_getAtKeyPath
// CHECK-NEXT: apply %{{.*}}<Self, Any>({{.*}})
}
}