Skip to content

Commit e4f9965

Browse files
committed
[ConstraintSystem] Fail key path capability inference if root is a placeholder
If root type of a key path has been determined to be a hole there is no reason to delay the inference decision which should be a failure because none of the components would be inferrable from a placeholder root.
1 parent 6afc307 commit e4f9965

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7648,6 +7648,13 @@ ConstraintSystem::inferKeyPathLiteralCapability(KeyPathExpr *keyPath) {
76487648
if (keyPath->hasSingleInvalidComponent())
76497649
return fail();
76507650

7651+
// If root is determined to be a hole it means that none of the components
7652+
// are resolvable and key path is not viable.
7653+
auto rootTy =
7654+
getFixedTypeRecursive(getKeyPathRootType(keyPath), /*wantRValue=*/false);
7655+
if (rootTy->isPlaceholder())
7656+
return fail();
7657+
76517658
auto mutability = KeyPathMutability::Writable;
76527659
for (unsigned i : indices(keyPath->getComponents())) {
76537660
auto &component = keyPath->getComponents()[i];

test/expr/unary/keypath/keypath.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -914,13 +914,13 @@ 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'}}
918917
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'}}
920918

921-
func provideValueButNotRoot<T>(_ fn: (T) -> String) {}
919+
func provideValueButNotRoot<T>(_ fn: (T) -> String) {} // expected-note 2 {{in call to function 'provideValueButNotRoot'}}
922920
provideValueButNotRoot(\.x) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}}
921+
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
923922
provideValueButNotRoot(\.x.y) // expected-error {{cannot infer key path type from context; consider explicitly specifying a root type}}
923+
// expected-error@-1 {{generic parameter 'T' could not be inferred}}
924924
provideValueButNotRoot(\String.foo) // expected-error {{value of type 'String' has no member 'foo'}}
925925

926926
func provideKPValueButNotRoot<T>(_ kp: KeyPath<T, String>) {}
@@ -1237,3 +1237,9 @@ func test_keypath_coercion_to_function() {
12371237
func test_keypath_application_with_composition(v: String, kp: any KeyPath<String, Int> & PP) {
12381238
_ = v[keyPath: kp] // Ok
12391239
}
1240+
1241+
func test_leading_dot_key_path_without_context() {
1242+
func test(_: AnyKeyPath?) {}
1243+
test(\.utf8)
1244+
// expected-error@-1 {{cannot infer key path type from context; consider explicitly specifying a root type}}
1245+
}

validation-test/Sema/SwiftUI/rdar84580119.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ 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'}}
2019
}
2120
}
2221

0 commit comments

Comments
 (0)