Skip to content

Commit d604047

Browse files
committed
When root type of a keypath is unresolved by the constraint system, use the root interface type for diagnosis.
1 parent ecdfb5d commit d604047

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

lib/Sema/CSDiag.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7098,6 +7098,19 @@ static bool diagnoseKeyPathComponents(ConstraintSystem &CS, KeyPathExpr *KPE,
70987098
Type rootType) {
70997099
auto &TC = CS.TC;
71007100

7101+
// The constraint system may have been unable to resolve the actual root
7102+
// type. The generic interface type of the root produces better
7103+
// diagnostics in this case.
7104+
if (rootType->hasUnresolvedType() && !KPE->isObjC()) {
7105+
if (auto ident = dyn_cast<ComponentIdentTypeRepr>(KPE->getRootType())) {
7106+
if (auto decl = ident->getBoundDecl()) {
7107+
if (auto metaType = decl->getInterfaceType()->castTo<MetatypeType>()) {
7108+
rootType = metaType->getInstanceType();
7109+
}
7110+
}
7111+
}
7112+
}
7113+
71017114
// The key path string we're forming.
71027115
SmallString<32> keyPathScratch;
71037116
llvm::raw_svector_ostream keyPathOS(keyPathScratch);

test/Constraints/keypath.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,18 @@ func test() {
1919

2020
let _ = C()[keyPath: \.i] // no warning for a read
2121
}
22+
23+
// SR-7339
24+
class Some<T, V> {
25+
init(keyPath: KeyPath<T, ((V) -> Void)?>) {
26+
}
27+
}
28+
29+
class Demo {
30+
var here: (() -> Void)?
31+
}
32+
33+
// FIXME: This error is better than it was, but the diagnosis should break it down more specifically to 'here's type.
34+
let some = Some(keyPath: \Demo.here)
35+
// expected-error@-1 {{cannot convert value of type 'ReferenceWritableKeyPath<Demo, (() -> Void)?>' to expected argument type 'KeyPath<_, ((_) -> Void)?>'}}
36+

0 commit comments

Comments
 (0)