Skip to content

Commit e2c94ad

Browse files
authored
Merge pull request #71896 from xedin/rdar-123638701
[CSApply] Optional chaining forces key path component to be r-value
2 parents 420859c + 7ad80b8 commit e2c94ad

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5116,7 +5116,8 @@ namespace {
51165116
!componentTy->getWithoutSpecifierType()->isEqual(leafTy)) {
51175117
auto component = KeyPathExpr::Component::forOptionalWrap(leafTy);
51185118
resolvedComponents.push_back(component);
5119-
componentTy = OptionalType::get(componentTy);
5119+
// Optional chaining forces the component to be r-value.
5120+
componentTy = OptionalType::get(componentTy->getWithoutSpecifierType());
51205121
}
51215122

51225123
// Set the resolved components, and cache their types.

test/SILGen/keypaths.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,3 +652,23 @@ struct Test {
652652
var codingPath: [any CodingKey] { codingStack.map(\.key) }
653653
// CHECK: keypath $KeyPath<CodingStackEntry, URICoderCodingKey>, (root $CodingStackEntry; stored_property #CodingStackEntry.key : $URICoderCodingKey)
654654
}
655+
656+
// rdar://123638701 - Make sure that optional chaining forces loads.
657+
func test_optional_chaining_with_function_conversion() {
658+
class Storage {}
659+
660+
class Elements {
661+
var db: Storage = Storage()
662+
}
663+
664+
class Source {
665+
var elements: Elements? = nil
666+
}
667+
668+
func test(data: [Source]) {
669+
// CHECK: {{.*}} = keypath $KeyPath<Source, Optional<Storage>>
670+
_ = data.compactMap(\.elements?.db)
671+
// CHECK: {{.*}} = keypath $KeyPath<Source, Storage>
672+
_ = data.compactMap(\.elements!.db)
673+
}
674+
}

0 commit comments

Comments
 (0)