Skip to content

Commit 9f21b95

Browse files
committed
[CSDiagnostics] A tailored diagnostic when passing key path as an argument to non-key path parameter
Produce a tailored diagnostic that omits a fully unresolved key path type (`KeyPath<_, _>`) when key path without an explicit root type is passed as an argument to non-keypath parameter type (i.e. `Int`).
1 parent 0832afe commit 9f21b95

File tree

4 files changed

+19
-0
lines changed

4 files changed

+19
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,10 @@ ERROR(cannot_convert_argument_value,none,
376376
"cannot convert value of type %0 to expected argument type %1",
377377
(Type,Type))
378378

379+
ERROR(cannot_convert_unresolved_key_path_argument_value,none,
380+
"cannot convert value of key path type to expected argument type %0",
381+
(Type))
382+
379383
ERROR(cannot_convert_argument_value_for_swift_func,none,
380384
"cannot convert value of type %0 to expected argument type %1 "
381385
"because %kind2 was not imported from C header",

lib/Sema/CSDiagnostics.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7295,6 +7295,18 @@ bool ArgumentMismatchFailure::diagnoseAsError() {
72957295

72967296
auto argType = getFromType();
72977297

7298+
// Unresolved key path argument requires a tailored diagnostic
7299+
// that doesn't mention a fallback type - `KeyPath<_, _>`.
7300+
if (argType->isKeyPath() && !isKnownKeyPathType(paramType)) {
7301+
auto keyPathTy = argType->castTo<BoundGenericType>();
7302+
auto rootTy = keyPathTy->getGenericArgs()[0];
7303+
if (rootTy->is<UnresolvedType>()) {
7304+
emitDiagnostic(diag::cannot_convert_unresolved_key_path_argument_value,
7305+
paramType);
7306+
return true;
7307+
}
7308+
}
7309+
72987310
if (paramType->isAnyObject()) {
72997311
emitDiagnostic(diag::cannot_convert_argument_value_anyobject, argType,
73007312
paramType);

test/expr/unary/keypath/keypath.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,9 @@ func testKeyPathHole() {
914914

915915
func f(_ i: Int) {}
916916
f(\.x) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} {{6-6=<#Root#>}}
917+
// expected-error@-1 {{cannot convert value of key path type to expected argument type 'Int'}}
917918
f(\.x.y) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}} {{6-6=<#Root#>}}
919+
// expected-error@-1 {{cannot convert value of key path type to expected argument type 'Int'}}
918920

919921
func provideValueButNotRoot<T>(_ fn: (T) -> String) {}
920922
provideValueButNotRoot(\.x) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}}

validation-test/Sema/SwiftUI/rdar84580119.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extension EnvironmentValues {
1616
set { self[\.MyHorizontalAlignmentEnvironmentKey.self] = newValue }
1717
// expected-error@-1 {{generic parameter 'K' could not be inferred}}
1818
// expected-error@-2 {{cannot infer key path type from context; consider explicitly specifying a root type}}
19+
// expected-error@-3 {{cannot convert value of key path type to expected argument type 'K.Type'}}
1920
}
2021
}
2122

0 commit comments

Comments
 (0)