Skip to content

Commit 9ae6813

Browse files
authored
Merge pull request #30040 from xedin/sr-11743
[ConstraintSystem] Look through l-value while checking whether dynami…
2 parents 6dd358d + 7d4db41 commit 9ae6813

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5571,7 +5571,15 @@ static bool isSelfRecursiveKeyPathDynamicMemberLookup(
55715571
return baseDecl == keyPathRootDecl;
55725572
}
55735573

5574-
if (baseTy->isEqual(keyPathRootTy))
5574+
// Previous base type could be r-value because that could be
5575+
// a base type of subscript "as written" for which we attempt
5576+
// a dynamic member lookup.
5577+
auto baseTy1 = baseTy->getRValueType();
5578+
// Root type of key path is always wrapped in an l-value
5579+
// before lookup is performed, so we need to unwrap that.
5580+
auto baseTy2 = keyPathRootTy->getRValueType();
5581+
5582+
if (baseTy1->isEqual(baseTy2))
55755583
return true;
55765584
}
55775585

@@ -5893,6 +5901,10 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
58935901
using KPDynamicMemberElt = LocatorPathElt::KeyPathDynamicMember;
58945902
if (auto kpElt = memberLocator->getLastElementAs<KPDynamicMemberElt>()) {
58955903
auto *keyPath = kpElt->getKeyPathDecl();
5904+
if (isSelfRecursiveKeyPathDynamicMemberLookup(*this, baseTy,
5905+
memberLocator))
5906+
return;
5907+
58965908
if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
58975909
// If this is an attempt to access read-only member via
58985910
// writable key path, let's fail this choice early.

test/Constraints/keypath_dynamic_member_lookup.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,3 +483,28 @@ func testDynamicMemberWithDefault(_ x: SR_11933) {
483483
// 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]])
484484
_ = \SR_11933.[]
485485
}
486+
487+
// SR-11743 - KeyPath Dynamic Member Lookup crash
488+
@dynamicMemberLookup
489+
protocol SR_11743_P {
490+
subscript(dynamicMember member: KeyPath<Self, Any>) -> Any { get }
491+
}
492+
493+
extension SR_11743_P {
494+
subscript(dynamicMember member: KeyPath<Self, Any>) -> Any {
495+
self[keyPath: member] // Ok
496+
// CHECK: function_ref @swift_getAtKeyPath
497+
// CHECK-NEXT: apply %{{.*}}<Self, Any>({{.*}})
498+
}
499+
}
500+
501+
@dynamicMemberLookup
502+
struct SR_11743_Struct {
503+
let value: Int
504+
505+
subscript<T>(dynamicMember member: KeyPath<Self, T>) -> T {
506+
return self[keyPath: member]
507+
// CHECK: function_ref @swift_getAtKeyPath
508+
// CHECK-NEXT: apply %{{.*}}<SR_11743_Struct, T>({{.*}})
509+
}
510+
}

0 commit comments

Comments
 (0)